当前位置:Gxlcms > 数据库问题 > C++使用Sqlite3,使用CppSQLite3的封装

C++使用Sqlite3,使用CppSQLite3的封装

时间:2021-07-01 10:21:17 帮助过:11人阅读

///////////////////////////////////////////////////////////////////////////// // CppSQLite3 - A C++ wrapper around the SQLite3 embedded database library. // // Copyright (c) 2004..2007 Rob Groves. All Rights Reserved. rob.groves@btinternet.com // // Permission to use, copy, modify, and distribute this software and its // documentation for any purpose, without fee, and without a written // agreement, is hereby granted, provided that the above copyright notice, // this paragraph and the following two paragraphs appear in all copies, // modifications, and distributions. // // IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST // PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, // EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF // ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // // V3.0 03/08/2004 -Initial Version for sqlite3 // // V3.1 16/09/2004 -Implemented getXXXXField using sqlite3 functions // -Added CppSQLiteDB3::tableExists() // // V3.2 01/07/2005 -Fixed execScalar to handle a NULL result // 12/07/2007 -Added CppSQLiteDB::IsAutoCommitOn() // -Added int64 functions to CppSQLite3Query // -Added Name based parameter binding to CppSQLite3Statement. //////////////////////////////////////////////////////////////////////////////// #ifndef _CppSQLite3_H_ #define _CppSQLite3_H_ #include "sqlite3.h" #include <cstdio> #include <cstring> #define CPPSQLITE_ERROR 1000 class CppSQLite3Exception { public: CppSQLite3Exception(const int nErrCode, char* szErrMess, bool bDeleteMsg=true); CppSQLite3Exception(const CppSQLite3Exception& e); virtual ~CppSQLite3Exception(); const int errorCode() { return mnErrCode; } const char* errorMessage() { return mpszErrMess; } static const char* errorCodeAsString(int nErrCode); private: int mnErrCode; char* mpszErrMess; }; class CppSQLite3Buffer { public: CppSQLite3Buffer(); ~CppSQLite3Buffer(); const char* format(const char* szFormat, ...); operator const char*() { return mpBuf; } void clear(); private: char* mpBuf; }; class CppSQLite3Binary { public: CppSQLite3Binary(); ~CppSQLite3Binary(); void setBinary(const unsigned char* pBuf, int nLen); void setEncoded(const unsigned char* pBuf); const unsigned char* getEncoded(); const unsigned char* getBinary(); int getBinaryLength(); unsigned char* allocBuffer(int nLen); void clear(); private: unsigned char* mpBuf; int mnBinaryLen; int mnBufferLen; int mnEncodedLen; bool mbEncoded; }; class CppSQLite3Query { public: CppSQLite3Query(); CppSQLite3Query(const CppSQLite3Query& rQuery); CppSQLite3Query(sqlite3* pDB, sqlite3_stmt* pVM, bool bEof, bool bOwnVM=true); CppSQLite3Query& operator=(const CppSQLite3Query& rQuery); virtual ~CppSQLite3Query(); 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); sqlite_int64 getInt64Field(int nField, sqlite_int64 nNullValue=0); sqlite_int64 getInt64Field(const char* szField, sqlite_int64 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 CppSQLite3Table { public: CppSQLite3Table(); CppSQLite3Table(const CppSQLite3Table& rTable); CppSQLite3Table(char** paszResults, int nRows, int nCols); virtual ~CppSQLite3Table(); CppSQLite3Table& operator=(const CppSQLite3Table& rTable); int numFields(); int numRows(); const char* fieldName(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=""); bool fieldIsNull(int nField); bool fieldIsNull(const char* szField); void setRow(int nRow); void finalize(); private: void checkResults(); int mnCols; int mnRows; int mnCurrentRow; char** mpaszResults; }; class CppSQLite3Statement { public: CppSQLite3Statement(); CppSQLite3Statement(const CppSQLite3Statement& rStatement); CppSQLite3Statement(sqlite3* pDB, sqlite3_stmt* pVM); virtual ~CppSQLite3Statement(); CppSQLite3Statement& operator=(const CppSQLite3Statement& rStatement); int execDML(); CppSQLite3Query execQuery(); void bind(int nParam, const char* szValue); void bind(int nParam, const int nValue); void bind(int nParam, const double dwValue); void bind(int nParam, const unsigned char* blobValue, int nLen); void bindNull(int nParam); int bindParameterIndex(const char* szParam); void bind(const char* szParam, const char* szValue); void bind(const char* szParam, const int nValue); void bind(const char* szParam, const double dwValue); void bind(const char* szParam, const unsigned char* blobValue, int nLen); void bindNull(const char* szParam); void reset(); void finalize(); private: void checkDB(); void checkVM(); sqlite3* mpDB; sqlite3_stmt* mpVM; }; class CppSQLite3DB { public: CppSQLite3DB(); virtual ~CppSQLite3DB(); void open(const char* szFile); void close(); bool tableExists(const char* szTable); int execDML(const char* szSQL); CppSQLite3Query execQuery(const char* szSQL); int execScalar(const char* szSQL, int nNullValue=0); CppSQLite3Table getTable(const char* szSQL); CppSQLite3Statement compileStatement(const char* szSQL); sqlite_int64 lastRowId(); void interrupt() { sqlite3_interrupt(mpDB); } void setBusyTimeout(int nMillisecs); static const char* SQLiteVersion() { return SQLITE_VERSION; } static const char* SQLiteHeaderVersion() { return SQLITE_VERSION; } static const char* SQLiteLibraryVersion() { return sqlite3_libversion(); } static int SQLiteLibraryVersionNumber() { return sqlite3_libversion_number(); } bool IsAutoCommitOn(); private: CppSQLite3DB(const CppSQLite3DB& db); CppSQLite3DB& operator=(const CppSQLite3DB& db); sqlite3_stmt* compile(const char* szSQL); void checkDB(); sqlite3* mpDB; int mnBusyTimeoutMs; }; #endif

CppSQLite3.cpp

////////////////////////////////////////////////////////////////////////////////
// CppSQLite3 - A C++ wrapper around the SQLite3 embedded database library.
//
// Copyright (c) 2004..2007 Rob Groves. All Rights Reserved. rob.groves@btinternet.com
// 
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose, without fee, and without a written
// agreement, is hereby granted, provided that the above copyright notice, 
// this paragraph and the following two paragraphs appear in all copies, 
// modifications, and distributions.
//
// IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
// PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
// EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
// ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// V3.0     03/08/2004  -Initial Version for sqlite3
//
// V3.1     16/09/2004  -Implemented getXXXXField using sqlite3 functions
//                      -Added CppSQLiteDB3::tableExists()
//
// V3.2     01/07/2005  -Fixed execScalar to handle a NULL result
//          12/07/2007  -Added int64 functions to CppSQLite3Query
//                      -Throw exception from CppSQLite3DB::close() if error
//                      -Trap above exception in CppSQLite3DB::~CppSQLite3DB()
//                      -Fix to CppSQLite3DB::compile() as provided by Dave Rollins.
//                      -sqlite3_prepare replaced with sqlite3_prepare_v2
//                      -Added Name based parameter binding to CppSQLite3Statement.
////////////////////////////////////////////////////////////////////////////////
#include "CppSQLite3.h"
#include <cstdlib>


// Named constant for passing to CppSQLite3Exception when passing it a string
// that cannot be deleted.
static const bool DONT_DELETE_MSG=false;

////////////////////////////////////////////////////////////////////////////////
// Prototypes for SQLite functions not included in SQLite DLL, but copied below
// from SQLite encode.c
////////////////////////////////////////////////////////////////////////////////
int sqlite3_encode_binary(const unsigned char *in, int n, unsigned char *out);
int sqlite3_decode_binary(const unsigned char *in, unsigned char *out);

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

CppSQLite3Exception::CppSQLite3Exception(const int nErrCode,
                                    char* szErrMess,
                                    bool bDeleteMsg/*=true*/) :
                                    mnErrCode(nErrCode)
{
    mpszErrMess = sqlite3_mprintf("%s[%d]: %s",
                                errorCodeAsString(nErrCode),
                                nErrCode,
                                szErrMess ? szErrMess : "");

    if (bDeleteMsg && szErrMess)
    {
        sqlite3_free(szErrMess);
    }
}


CppSQLite3Exception::CppSQLite3Exception(const CppSQLite3Exception&  e) :
                                    mnErrCode(e.mnErrCode)
{
    mpszErrMess = 0;
    if (e.mpszErrMess)
    {
        mpszErrMess = sqlite3_mprintf("%s", e.mpszErrMess);
    }
}


const char* CppSQLite3Exception::errorCodeAsString(int nErrCode)
{
    switch (nErrCode)
    {
        case SQLITE_OK          : return "SQLITE_OK";
        case SQLITE_ERROR       : return "SQLITE_ERROR";
        case SQLITE_INTERNAL    : return "SQLITE_INTERNAL";
        case SQLITE_PERM        : return "SQLITE_PERM";
        case SQLITE_ABORT       : return "SQLITE_ABORT";
        case SQLITE_BUSY        : return "SQLITE_BUSY";
        case SQLITE_LOCKED      : return "SQLITE_LOCKED";
        case SQLITE_NOMEM       : return "SQLITE_NOMEM";
        case SQLITE_READONLY    : return "SQLITE_READONLY";
        case SQLITE_INTERRUPT   : return "SQLITE_INTERRUPT";
        case SQLITE_IOERR       : return "SQLITE_IOERR";
        case SQLITE_CORRUPT     : return "SQLITE_CORRUPT";
        case SQLITE_NOTFOUND    : return "SQLITE_NOTFOUND";
        case SQLITE_FULL        : return "SQLITE_FULL";
        case SQLITE_CANTOPEN    : return "SQLITE_CANTOPEN";
        case SQLITE_PROTOCOL    : return "SQLITE_PROTOCOL";
        case SQLITE_EMPTY       : return "SQLITE_EMPTY";
        case SQLITE_SCHEMA      : return "SQLITE_SCHEMA";
        case SQLITE_TOOBIG      : return "SQLITE_TOOBIG";
        case SQLITE_CONSTRAINT  : return "SQLITE_CONSTRAINT";
        case SQLITE_MISMATCH    : return "SQLITE_MISMATCH";
        case SQLITE_MISUSE      : return "SQLITE_MISUSE";
        case SQLITE_NOLFS       : return "SQLITE_NOLFS";
        case SQLITE_AUTH        : return "SQLITE_AUTH";
        case SQLITE_FORMAT      : return "SQLITE_FORMAT";
        case SQLITE_RANGE       : return "SQLITE_RANGE";
        case SQLITE_ROW         : return "SQLITE_ROW";
        case SQLITE_DONE        : return "SQLITE_DONE";
        case CPPSQLITE_ERROR    : return "CPPSQLITE_ERROR";
        default: return "UNKNOWN_ERROR";
    }
}


CppSQLite3Exception::~CppSQLite3Exception()
{
    if (mpszErrMess)
    {
        sqlite3_free(mpszErrMess);
        mpszErrMess = 0;
    }
}


////////////////////////////////////////////////////////////////////////////////

CppSQLite3Buffer::CppSQLite3Buffer()
{
    mpBuf = 0;
}


CppSQLite3Buffer::~CppSQLite3Buffer()
{
    clear();
}


void CppSQLite3Buffer::clear()
{
    if (mpBuf)
    {
        sqlite3_free(mpBuf);
        mpBuf = 0;
    }

}


const char* CppSQLite3Buffer::format(const char* szFormat, ...)
{
    clear();
    va_list va;
    va_start(va, szFormat);
    mpBuf = sqlite3_vmprintf(szFormat, va);
    va_end(va);
    return mpBuf;
}


////////////////////////////////////////////////////////////////////////////////

CppSQLite3Binary::CppSQLite3Binary() :
                        mpBuf(0),
                        mnBinaryLen(0),
                        mnBufferLen(0),
                        mnEncodedLen(0),
                        mbEncoded(false)
{
}


CppSQLite3Binary::~CppSQLite3Binary()
{
    clear();
}


void CppSQLite3Binary::setBinary(const unsigned char* pBuf, int nLen)
{
    mpBuf = allocBuffer(nLen);
    memcpy(mpBuf, pBuf, nLen);
}


void CppSQLite3Binary::setEncoded(const unsigned char* pBuf)
{
    clear();

    mnEncodedLen = strlen((const char*)pBuf);
    mnBufferLen = mnEncodedLen + 1; // Allow for NULL terminator

    mpBuf = (unsigned char*)malloc(mnBufferLen);

    if (!mpBuf)
    {
        throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                "Cannot allocate memory",
                                DONT_DELETE_MSG);
    }

    memcpy(mpBuf, pBuf, mnBufferLen);
    mbEncoded = true;
}


const unsigned char* CppSQLite3Binary::getEncoded()
{
    if (!mbEncoded)
    {
        unsigned char* ptmp = (unsigned char*)malloc(mnBinaryLen);
        memcpy(ptmp, mpBuf, mnBinaryLen);
        mnEncodedLen = sqlite3_encode_binary(ptmp, mnBinaryLen, mpBuf);
        free(ptmp);
        mbEncoded = true;
    }

    return mpBuf;
}


const unsigned char* CppSQLite3Binary::getBinary()
{
    if (mbEncoded)
    {
        // in/out buffers can be the same
        mnBinaryLen = sqlite3_decode_binary(mpBuf, mpBuf);

        if (mnBinaryLen == -1)
        {
            throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                    "Cannot decode binary",
                                    DONT_DELETE_MSG);
        }

        mbEncoded = false;
    }

    return mpBuf;
}


int CppSQLite3Binary::getBinaryLength()
{
    getBinary();
    return mnBinaryLen;
}


unsigned char* CppSQLite3Binary::allocBuffer(int nLen)
{
    clear();

    // Allow extra space for encoded binary as per comments in
    // SQLite encode.c See bottom of this file for implementation
    // of SQLite functions use 3 instead of 2 just to be sure ;-)
    mnBinaryLen = nLen;
    mnBufferLen = 3 + (257*nLen)/254;

    mpBuf = (unsigned char*)malloc(mnBufferLen);

    if (!mpBuf)
    {
        throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                "Cannot allocate memory",
                                DONT_DELETE_MSG);
    }

    mbEncoded = false;

    return mpBuf;
}


void CppSQLite3Binary::clear()
{
    if (mpBuf)
    {
        mnBinaryLen = 0;
        mnBufferLen = 0;
        free(mpBuf);
        mpBuf = 0;
    }
}


////////////////////////////////////////////////////////////////////////////////

CppSQLite3Query::CppSQLite3Query()
{
    mpVM = 0;
    mbEof = true;
    mnCols = 0;
    mbOwnVM = false;
}


CppSQLite3Query::CppSQLite3Query(const CppSQLite3Query& rQuery)
{
    mpVM = rQuery.mpVM;
    // Only one object can own the VM
    const_cast<CppSQLite3Query&>(rQuery).mpVM = 0;
    mbEof = rQuery.mbEof;
    mnCols = rQuery.mnCols;
    mbOwnVM = rQuery.mbOwnVM;
}


CppSQLite3Query::CppSQLite3Query(sqlite3* pDB,
                            sqlite3_stmt* pVM,
                            bool bEof,
                            bool bOwnVM/*=true*/)
{
    mpDB = pDB;
    mpVM = pVM;
    mbEof = bEof;
    mnCols = sqlite3_column_count(mpVM);
    mbOwnVM = bOwnVM;
}


CppSQLite3Query::~CppSQLite3Query()
{
    try
    {
        finalize();
    }
    catch (...)
    {
    }
}


CppSQLite3Query& CppSQLite3Query::operator=(const CppSQLite3Query& rQuery)
{
    try
    {
        finalize();
    }
    catch (...)
    {
    }
    mpVM = rQuery.mpVM;
    // Only one object can own the VM
    const_cast<CppSQLite3Query&>(rQuery).mpVM = 0;
    mbEof = rQuery.mbEof;
    mnCols = rQuery.mnCols;
    mbOwnVM = rQuery.mbOwnVM;
    return *this;
}


int CppSQLite3Query::numFields()
{
    checkVM();
    return mnCols;
}


const char* CppSQLite3Query::fieldValue(int nField)
{
    checkVM();

    if (nField < 0 || nField > mnCols-1)
    {
        throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                "Invalid field index requested",
                                DONT_DELETE_MSG);
    }

    return (const char*)sqlite3_column_text(mpVM, nField);
}


const char* CppSQLite3Query::fieldValue(const char* szField)
{
    int nField = fieldIndex(szField);
    return (const char*)sqlite3_column_text(mpVM, nField);
}


int CppSQLite3Query::getIntField(int nField, int nNullValue/*=0*/)
{
    if (fieldDataType(nField) == SQLITE_NULL)
    {
        return nNullValue;
    }
    else
    {
        return sqlite3_column_int(mpVM, nField);
    }
}


int CppSQLite3Query::getIntField(const char* szField, int nNullValue/*=0*/)
{
    int nField = fieldIndex(szField);
    return getIntField(nField, nNullValue);
}


sqlite_int64 CppSQLite3Query::getInt64Field(int nField, sqlite_int64 nNullValue/*=0*/)
{
    if (fieldDataType(nField) == SQLITE_NULL)
    {
        return nNullValue;
    }
    else
    {
        return sqlite3_column_int64(mpVM, nField);
    }
}


sqlite_int64 CppSQLite3Query::getInt64Field(const char* szField, sqlite_int64 nNullValue/*=0*/)
{
    int nField = fieldIndex(szField);
    return getInt64Field(nField, nNullValue);
}


double CppSQLite3Query::getFloatField(int nField, double fNullValue/*=0.0*/)
{
    if (fieldDataType(nField) == SQLITE_NULL)
    {
        return fNullValue;
    }
    else
    {
        return sqlite3_column_double(mpVM, nField);
    }
}


double CppSQLite3Query::getFloatField(const char* szField, double fNullValue/*=0.0*/)
{
    int nField = fieldIndex(szField);
    return getFloatField(nField, fNullValue);
}


const char* CppSQLite3Query::getStringField(int nField, const char* szNullValue/*=""*/)
{
    if (fieldDataType(nField) == SQLITE_NULL)
    {
        return szNullValue;
    }
    else
    {
        return (const char*)sqlite3_column_text(mpVM, nField);
    }
}


const char* CppSQLite3Query::getStringField(const char* szField, const char* szNullValue/*=""*/)
{
    int nField = fieldIndex(szField);
    return getStringField(nField, szNullValue);
}


const unsigned char* CppSQLite3Query::getBlobField(int nField, int& nLen)
{
    checkVM();

    if (nField < 0 || nField > mnCols-1)
    {
        throw CppSQLite3Exception(CPPSQLITE_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* CppSQLite3Query::getBlobField(const char* szField, int& nLen)
{
    int nField = fieldIndex(szField);
    return getBlobField(nField, nLen);
}


bool CppSQLite3Query::fieldIsNull(int nField)
{
    return (fieldDataType(nField) == SQLITE_NULL);
}


bool CppSQLite3Query::fieldIsNull(const char* szField)
{
    int nField = fieldIndex(szField);
    return (fieldDataType(nField) == SQLITE_NULL);
}


int CppSQLite3Query::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 CppSQLite3Exception(CPPSQLITE_ERROR,
                            "Invalid field name requested",
                            DONT_DELETE_MSG);
}


const char* CppSQLite3Query::fieldName(int nCol)
{
    checkVM();

    if (nCol < 0 || nCol > mnCols-1)
    {
        throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                "Invalid field index requested",
                                DONT_DELETE_MSG);
    }

    return sqlite3_column_name(mpVM, nCol);
}


const char* CppSQLite3Query::fieldDeclType(int nCol)
{
    checkVM();

    if (nCol < 0 || nCol > mnCols-1)
    {
        throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                "Invalid field index requested",
                                DONT_DELETE_MSG);
    }

    return sqlite3_column_decltype(mpVM, nCol);
}


int CppSQLite3Query::fieldDataType(int nCol)
{
    checkVM();

    if (nCol < 0 || nCol > mnCols-1)
    {
        throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                "Invalid field index requested",
                                DONT_DELETE_MSG);
    }

    return sqlite3_column_type(mpVM, nCol);
}


bool CppSQLite3Query::eof()
{
    checkVM();
    return mbEof;
}


void CppSQLite3Query::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_finalize(mpVM);
        mpVM = 0;
        const char* szError = sqlite3_errmsg(mpDB);
        throw CppSQLite3Exception(nRet,
                                (char*)szError,
                                DONT_DELETE_MSG);
    }
}


void CppSQLite3Query::finalize()
{
    if (mpVM && mbOwnVM)
    {
        int nRet = sqlite3_finalize(mpVM);
        mpVM = 0;
        if (nRet != SQLITE_OK)
        {
            const char* szError = sqlite3_errmsg(mpDB);
            throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
        }
    }
}


void CppSQLite3Query::checkVM()
{
    if (mpVM == 0)
    {
        throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                "Null Virtual Machine pointer",
                                DONT_DELETE_MSG);
    }
}


////////////////////////////////////////////////////////////////////////////////

CppSQLite3Table::CppSQLite3Table()
{
    mpaszResults = 0;
    mnRows = 0;
    mnCols = 0;
    mnCurrentRow = 0;
}


CppSQLite3Table::CppSQLite3Table(const CppSQLite3Table& rTable)
{
    mpaszResults = rTable.mpaszResults;
    // Only one object can own the results
    const_cast<CppSQLite3Table&>(rTable).mpaszResults = 0;
    mnRows = rTable.mnRows;
    mnCols = rTable.mnCols;
    mnCurrentRow = rTable.mnCurrentRow;
}


CppSQLite3Table::CppSQLite3Table(char** paszResults, int nRows, int nCols)
{
    mpaszResults = paszResults;
    mnRows = nRows;
    mnCols = nCols;
    mnCurrentRow = 0;
}


CppSQLite3Table::~CppSQLite3Table()
{
    try
    {
        finalize();
    }
    catch (...)
    {
    }
}


CppSQLite3Table& CppSQLite3Table::operator=(const CppSQLite3Table& rTable)
{
    try
    {
        finalize();
    }
    catch (...)
    {
    }
    mpaszResults = rTable.mpaszResults;
    // Only one object can own the results
    const_cast<CppSQLite3Table&>(rTable).mpaszResults = 0;
    mnRows = rTable.mnRows;
    mnCols = rTable.mnCols;
    mnCurrentRow = rTable.mnCurrentRow;
    return *this;
}


void CppSQLite3Table::finalize()
{
    if (mpaszResults)
    {
        sqlite3_free_table(mpaszResults);
        mpaszResults = 0;
    }
}


int CppSQLite3Table::numFields()
{
    checkResults();
    return mnCols;
}


int CppSQLite3Table::numRows()
{
    checkResults();
    return mnRows;
}


const char* CppSQLite3Table::fieldValue(int nField)
{
    checkResults();

    if (nField < 0 || nField > mnCols-1)
    {
        throw CppSQLite3Exception(CPPSQLITE_ERROR,
                                "Invalid field index requested",
                               

人气教程排行