src/cppsqlite3.cc

00001 
00002 // CppSQLite3 - A C++ wrapper around the SQLite3 embedded database library.
00003 //
00004 // Copyright (c) 2004 Rob Groves. All Rights Reserved. rob.groves@btinternet.com
00005 // 
00006 // Permission to use, copy, modify, and distribute this software and its
00007 // documentation for any purpose, without fee, and without a written
00008 // agreement, is hereby granted, provided that the above copyright notice, 
00009 // this paragraph and the following two paragraphs appear in all copies, 
00010 // modifications, and distributions.
00011 //
00012 // IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
00013 // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
00014 // PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
00015 // EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00016 //
00017 // THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
00018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00019 // PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
00020 // ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION
00021 // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00022 //
00023 // V3.0         03/08/2004      -Initial Version for sqlite3
00024 //
00025 // V3.1         16/09/2004      -Implemented getXXXXField using sqlite3 functions
00026 //                                              -Added CppSQLiteDB3::tableExists()
00028 #include "cppsqlite3.h"
00029 #include <cstdlib>
00030 
00031 
00032 // Named constant for passing to CppSQLite3Exception when passing it a string
00033 // that cannot be deleted.
00034 static const bool DONT_DELETE_MSG=false;
00035 
00037 // Prototypes for SQLite functions not included in SQLite DLL, but copied below
00038 // from SQLite encode.c
00040 int sqlite3_encode_binary(const unsigned char *in, int n, unsigned char *out);
00041 int sqlite3_decode_binary(const unsigned char *in, unsigned char *out);
00042 
00044 
00046 
00047 CppSQLite3Exception::CppSQLite3Exception(const int nErrCode,
00048                                                                         char* szErrMess,
00049                                                                         bool bDeleteMsg/*=true*/) :
00050                                                                         mnErrCode(nErrCode)
00051 {
00052         mpszErrMess = sqlite3_mprintf("%s[%d]: %s",
00053                                                                 errorCodeAsString(nErrCode),
00054                                                                 nErrCode,
00055                                                                 szErrMess ? szErrMess : "");
00056 
00057         if (bDeleteMsg && szErrMess)
00058         {
00059                 sqlite3_free(szErrMess);
00060         }
00061 }
00062 
00063                                                                         
00064 CppSQLite3Exception::CppSQLite3Exception(const CppSQLite3Exception&  e) :
00065                                                                         mnErrCode(e.mnErrCode)
00066 {
00067         mpszErrMess = 0;
00068         if (e.mpszErrMess)
00069         {
00070                 mpszErrMess = sqlite3_mprintf("%s", e.mpszErrMess);
00071         }
00072 }
00073 
00074 
00075 const char* CppSQLite3Exception::errorCodeAsString(int nErrCode)
00076 {
00077         switch (nErrCode)
00078         {
00079                 case SQLITE_OK          : return "SQLITE_OK";
00080                 case SQLITE_ERROR       : return "SQLITE_ERROR";
00081                 case SQLITE_INTERNAL    : return "SQLITE_INTERNAL";
00082                 case SQLITE_PERM        : return "SQLITE_PERM";
00083                 case SQLITE_ABORT       : return "SQLITE_ABORT";
00084                 case SQLITE_BUSY        : return "SQLITE_BUSY";
00085                 case SQLITE_LOCKED      : return "SQLITE_LOCKED";
00086                 case SQLITE_NOMEM       : return "SQLITE_NOMEM";
00087                 case SQLITE_READONLY    : return "SQLITE_READONLY";
00088                 case SQLITE_INTERRUPT   : return "SQLITE_INTERRUPT";
00089                 case SQLITE_IOERR       : return "SQLITE_IOERR";
00090                 case SQLITE_CORRUPT     : return "SQLITE_CORRUPT";
00091                 case SQLITE_NOTFOUND    : return "SQLITE_NOTFOUND";
00092                 case SQLITE_FULL        : return "SQLITE_FULL";
00093                 case SQLITE_CANTOPEN    : return "SQLITE_CANTOPEN";
00094                 case SQLITE_PROTOCOL    : return "SQLITE_PROTOCOL";
00095                 case SQLITE_EMPTY       : return "SQLITE_EMPTY";
00096                 case SQLITE_SCHEMA      : return "SQLITE_SCHEMA";
00097                 case SQLITE_TOOBIG      : return "SQLITE_TOOBIG";
00098                 case SQLITE_CONSTRAINT  : return "SQLITE_CONSTRAINT";
00099                 case SQLITE_MISMATCH    : return "SQLITE_MISMATCH";
00100                 case SQLITE_MISUSE      : return "SQLITE_MISUSE";
00101                 case SQLITE_NOLFS       : return "SQLITE_NOLFS";
00102                 case SQLITE_AUTH        : return "SQLITE_AUTH";
00103                 case SQLITE_FORMAT      : return "SQLITE_FORMAT";
00104                 case SQLITE_RANGE       : return "SQLITE_RANGE";
00105                 case SQLITE_ROW         : return "SQLITE_ROW";
00106                 case SQLITE_DONE        : return "SQLITE_DONE";
00107                 case CPPSQLITE_ERROR    : return "CPPSQLITE_ERROR";
00108                 default: return "UNKNOWN_ERROR";
00109         }
00110 }
00111 
00112 
00113 CppSQLite3Exception::~CppSQLite3Exception()
00114 {
00115         if (mpszErrMess)
00116         {
00117                 sqlite3_free(mpszErrMess);
00118                 mpszErrMess = 0;
00119         }
00120 }
00121 
00122 
00124 
00125 CppSQLite3Buffer::CppSQLite3Buffer()
00126 {
00127         mpBuf = 0;
00128 }
00129 
00130 
00131 CppSQLite3Buffer::~CppSQLite3Buffer()
00132 {
00133         clear();
00134 }
00135 
00136 
00137 void CppSQLite3Buffer::clear()
00138 {
00139         if (mpBuf)
00140         {
00141                 sqlite3_free(mpBuf);
00142                 mpBuf = 0;
00143         }
00144 
00145 }
00146 
00147 
00148 const char* CppSQLite3Buffer::format(const char* szFormat, ...)
00149 {
00150         clear();
00151         va_list va;
00152         va_start(va, szFormat);
00153         mpBuf = sqlite3_vmprintf(szFormat, va);
00154         va_end(va);
00155         return mpBuf;
00156 }
00157 
00158 
00160 
00161 CppSQLite3Binary::CppSQLite3Binary() :
00162                                                 mpBuf(0),
00163                                                 mnBinaryLen(0),
00164                                                 mnBufferLen(0),
00165                                                 mnEncodedLen(0),
00166                                                 mbEncoded(false)
00167 {
00168 }
00169 
00170 
00171 CppSQLite3Binary::~CppSQLite3Binary()
00172 {
00173         clear();
00174 }
00175 
00176 
00177 void CppSQLite3Binary::setBinary(const unsigned char* pBuf, int nLen)
00178 {
00179         mpBuf = allocBuffer(nLen);
00180         memcpy(mpBuf, pBuf, nLen);
00181 }
00182 
00183 
00184 void CppSQLite3Binary::setEncoded(const unsigned char* pBuf)
00185 {
00186         clear();
00187 
00188         mnEncodedLen = strlen((const char*)pBuf);
00189         mnBufferLen = mnEncodedLen + 1; // Allow for NULL terminator
00190 
00191         mpBuf = (unsigned char*)malloc(mnBufferLen);
00192 
00193         if (!mpBuf)
00194         {
00195                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00196                                                                 "Cannot allocate memory",
00197                                                                 DONT_DELETE_MSG);
00198         }
00199 
00200         memcpy(mpBuf, pBuf, mnBufferLen);
00201         mbEncoded = true;
00202 }
00203 
00204 
00205 const unsigned char* CppSQLite3Binary::getEncoded()
00206 {
00207         if (!mbEncoded)
00208         {
00209                 unsigned char* ptmp = (unsigned char*)malloc(mnBinaryLen);
00210                 memcpy(ptmp, mpBuf, mnBinaryLen);
00211                 mnEncodedLen = sqlite3_encode_binary(ptmp, mnBinaryLen, mpBuf);
00212                 free(ptmp);
00213                 mbEncoded = true;
00214         }
00215 
00216         return mpBuf;
00217 }
00218 
00219 
00220 const unsigned char* CppSQLite3Binary::getBinary()
00221 {
00222         if (mbEncoded)
00223         {
00224                 // in/out buffers can be the same
00225                 mnBinaryLen = sqlite3_decode_binary(mpBuf, mpBuf);
00226 
00227                 if (mnBinaryLen == -1)
00228                 {
00229                         throw CppSQLite3Exception(CPPSQLITE_ERROR,
00230                                                                         "Cannot decode binary",
00231                                                                         DONT_DELETE_MSG);
00232                 }
00233 
00234                 mbEncoded = false;
00235         }
00236 
00237         return mpBuf;
00238 }
00239 
00240 
00241 int CppSQLite3Binary::getBinaryLength()
00242 {
00243         getBinary();
00244         return mnBinaryLen;
00245 }
00246 
00247 
00248 unsigned char* CppSQLite3Binary::allocBuffer(int nLen)
00249 {
00250         clear();
00251 
00252         // Allow extra space for encoded binary as per comments in
00253         // SQLite encode.c See bottom of this file for implementation
00254         // of SQLite functions use 3 instead of 2 just to be sure ;-)
00255         mnBinaryLen = nLen;
00256         mnBufferLen = 3 + (257*nLen)/254;
00257 
00258         mpBuf = (unsigned char*)malloc(mnBufferLen);
00259 
00260         if (!mpBuf)
00261         {
00262                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00263                                                                 "Cannot allocate memory",
00264                                                                 DONT_DELETE_MSG);
00265         }
00266 
00267         mbEncoded = false;
00268 
00269         return mpBuf;
00270 }
00271 
00272 
00273 void CppSQLite3Binary::clear()
00274 {
00275         if (mpBuf)
00276         {
00277                 mnBinaryLen = 0;
00278                 mnBufferLen = 0;
00279                 free(mpBuf);
00280                 mpBuf = 0;
00281         }
00282 }
00283 
00284 
00286 
00287 CppSQLite3Query::CppSQLite3Query()
00288 {
00289         mpVM = 0;
00290         mbEof = true;
00291         mnCols = 0;
00292         mbOwnVM = false;
00293 }
00294 
00295 
00296 CppSQLite3Query::CppSQLite3Query(const CppSQLite3Query& rQuery)
00297 {
00298         mpVM = rQuery.mpVM;
00299         // Only one object can own the VM
00300         const_cast<CppSQLite3Query&>(rQuery).mpVM = 0;
00301         mbEof = rQuery.mbEof;
00302         mnCols = rQuery.mnCols;
00303         mbOwnVM = rQuery.mbOwnVM;
00304 }
00305 
00306 
00307 CppSQLite3Query::CppSQLite3Query(sqlite3* pDB,
00308                                                         sqlite3_stmt* pVM,
00309                                                         bool bEof,
00310                                                         bool bOwnVM/*=true*/)
00311 {
00312         mpDB = pDB;
00313         mpVM = pVM;
00314         mbEof = bEof;
00315         mnCols = sqlite3_column_count(mpVM);
00316         mbOwnVM = bOwnVM;
00317 }
00318 
00319 
00320 CppSQLite3Query::~CppSQLite3Query()
00321 {
00322         try
00323         {
00324                 finalize();
00325         }
00326         catch (...)
00327         {
00328         }
00329 }
00330 
00331 
00332 CppSQLite3Query& CppSQLite3Query::operator=(const CppSQLite3Query& rQuery)
00333 {
00334         try
00335         {
00336                 finalize();
00337         }
00338         catch (...)
00339         {
00340         }
00341         mpVM = rQuery.mpVM;
00342         // Only one object can own the VM
00343         const_cast<CppSQLite3Query&>(rQuery).mpVM = 0;
00344         mbEof = rQuery.mbEof;
00345         mnCols = rQuery.mnCols;
00346         mbOwnVM = rQuery.mbOwnVM;
00347         return *this;
00348 }
00349 
00350 
00351 int CppSQLite3Query::numFields()
00352 {
00353         checkVM();
00354         return mnCols;
00355 }
00356 
00357 
00358 const char* CppSQLite3Query::fieldValue(int nField)
00359 {
00360         checkVM();
00361 
00362         if (nField < 0 || nField > mnCols-1)
00363         {
00364                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00365                                                                 "Invalid field index requested",
00366                                                                 DONT_DELETE_MSG);
00367         }
00368 
00369         return (const char*)sqlite3_column_text(mpVM, nField);
00370 }
00371 
00372 
00373 const char* CppSQLite3Query::fieldValue(const char* szField)
00374 {
00375         int nField = fieldIndex(szField);
00376         return (const char*)sqlite3_column_text(mpVM, nField);
00377 }
00378 
00379 
00380 int CppSQLite3Query::getIntField(int nField, int nNullValue/*=0*/)
00381 {
00382         if (fieldDataType(nField) == SQLITE_NULL)
00383         {
00384                 return nNullValue;
00385         }
00386         else
00387         {
00388                 return sqlite3_column_int(mpVM, nField);
00389         }
00390 }
00391 
00392 
00393 int CppSQLite3Query::getIntField(const char* szField, int nNullValue/*=0*/)
00394 {
00395         int nField = fieldIndex(szField);
00396         return getIntField(nField, nNullValue);
00397 }
00398 
00399 
00400 double CppSQLite3Query::getFloatField(int nField, double fNullValue/*=0.0*/)
00401 {
00402         if (fieldDataType(nField) == SQLITE_NULL)
00403         {
00404                 return fNullValue;
00405         }
00406         else
00407         {
00408                 return sqlite3_column_double(mpVM, nField);
00409         }
00410 }
00411 
00412 
00413 double CppSQLite3Query::getFloatField(const char* szField, double fNullValue/*=0.0*/)
00414 {
00415         int nField = fieldIndex(szField);
00416         return getFloatField(nField, fNullValue);
00417 }
00418 
00419 
00420 const char* CppSQLite3Query::getStringField(int nField, const char* szNullValue/*=""*/)
00421 {
00422         if (fieldDataType(nField) == SQLITE_NULL)
00423         {
00424                 return szNullValue;
00425         }
00426         else
00427         {
00428                 return (const char*)sqlite3_column_text(mpVM, nField);
00429         }
00430 }
00431 
00432 
00433 const char* CppSQLite3Query::getStringField(const char* szField, const char* szNullValue/*=""*/)
00434 {
00435         int nField = fieldIndex(szField);
00436         return getStringField(nField, szNullValue);
00437 }
00438 
00439 
00440 const unsigned char* CppSQLite3Query::getBlobField(int nField, int& nLen)
00441 {
00442         checkVM();
00443 
00444         if (nField < 0 || nField > mnCols-1)
00445         {
00446                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00447                                                                 "Invalid field index requested",
00448                                                                 DONT_DELETE_MSG);
00449         }
00450 
00451         nLen = sqlite3_column_bytes(mpVM, nField);
00452         return (const unsigned char*)sqlite3_column_blob(mpVM, nField);
00453 }
00454 
00455 
00456 const unsigned char* CppSQLite3Query::getBlobField(const char* szField, int& nLen)
00457 {
00458         int nField = fieldIndex(szField);
00459         return getBlobField(nField, nLen);
00460 }
00461 
00462 
00463 bool CppSQLite3Query::fieldIsNull(int nField)
00464 {
00465         return (fieldDataType(nField) == SQLITE_NULL);
00466 }
00467 
00468 
00469 bool CppSQLite3Query::fieldIsNull(const char* szField)
00470 {
00471         int nField = fieldIndex(szField);
00472         return (fieldDataType(nField) == SQLITE_NULL);
00473 }
00474 
00475 
00476 int CppSQLite3Query::fieldIndex(const char* szField)
00477 {
00478         checkVM();
00479 
00480         if (szField)
00481         {
00482                 for (int nField = 0; nField < mnCols; nField++)
00483                 {
00484                         const char* szTemp = sqlite3_column_name(mpVM, nField);
00485 
00486                         if (strcmp(szField, szTemp) == 0)
00487                         {
00488                                 return nField;
00489                         }
00490                 }
00491         }
00492 
00493         throw CppSQLite3Exception(CPPSQLITE_ERROR,
00494                                                         "Invalid field name requested",
00495                                                         DONT_DELETE_MSG);
00496 }
00497 
00498 
00499 const char* CppSQLite3Query::fieldName(int nCol)
00500 {
00501         checkVM();
00502 
00503         if (nCol < 0 || nCol > mnCols-1)
00504         {
00505                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00506                                                                 "Invalid field index requested",
00507                                                                 DONT_DELETE_MSG);
00508         }
00509 
00510         return sqlite3_column_name(mpVM, nCol);
00511 }
00512 
00513 
00514 const char* CppSQLite3Query::fieldDeclType(int nCol)
00515 {
00516         checkVM();
00517 
00518         if (nCol < 0 || nCol > mnCols-1)
00519         {
00520                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00521                                                                 "Invalid field index requested",
00522                                                                 DONT_DELETE_MSG);
00523         }
00524 
00525         return sqlite3_column_decltype(mpVM, nCol);
00526 }
00527 
00528 
00529 int CppSQLite3Query::fieldDataType(int nCol)
00530 {
00531         checkVM();
00532 
00533         if (nCol < 0 || nCol > mnCols-1)
00534         {
00535                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00536                                                                 "Invalid field index requested",
00537                                                                 DONT_DELETE_MSG);
00538         }
00539 
00540         return sqlite3_column_type(mpVM, nCol);
00541 }
00542 
00543 
00544 bool CppSQLite3Query::eof()
00545 {
00546         checkVM();
00547         return mbEof;
00548 }
00549 
00550 
00551 void CppSQLite3Query::nextRow()
00552 {
00553         checkVM();
00554 
00555         int nRet = sqlite3_step(mpVM);
00556 
00557         if (nRet == SQLITE_DONE)
00558         {
00559                 // no rows
00560                 mbEof = true;
00561         }
00562         else if (nRet == SQLITE_ROW)
00563         {
00564                 // more rows, nothing to do
00565         }
00566         else
00567         {
00568                 nRet = sqlite3_finalize(mpVM);
00569                 mpVM = 0;
00570                 const char* szError = sqlite3_errmsg(mpDB);
00571                 throw CppSQLite3Exception(nRet,
00572                                                                 (char*)szError,
00573                                                                 DONT_DELETE_MSG);
00574         }
00575 }
00576 
00577 
00578 void CppSQLite3Query::finalize()
00579 {
00580         if (mpVM && mbOwnVM)
00581         {
00582                 int nRet = sqlite3_finalize(mpVM);
00583                 mpVM = 0;
00584                 if (nRet != SQLITE_OK)
00585                 {
00586                         const char* szError = sqlite3_errmsg(mpDB);
00587                         throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
00588                 }
00589         }
00590 }
00591 
00592 
00593 void CppSQLite3Query::checkVM()
00594 {
00595         if (mpVM == 0)
00596         {
00597                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00598                                                                 "Null Virtual Machine pointer",
00599                                                                 DONT_DELETE_MSG);
00600         }
00601 }
00602 
00603 
00605 
00606 CppSQLite3Table::CppSQLite3Table()
00607 {
00608         mpaszResults = 0;
00609         mnRows = 0;
00610         mnCols = 0;
00611         mnCurrentRow = 0;
00612 }
00613 
00614 
00615 CppSQLite3Table::CppSQLite3Table(const CppSQLite3Table& rTable)
00616 {
00617         mpaszResults = rTable.mpaszResults;
00618         // Only one object can own the results
00619         const_cast<CppSQLite3Table&>(rTable).mpaszResults = 0;
00620         mnRows = rTable.mnRows;
00621         mnCols = rTable.mnCols;
00622         mnCurrentRow = rTable.mnCurrentRow;
00623 }
00624 
00625 
00626 CppSQLite3Table::CppSQLite3Table(char** paszResults, int nRows, int nCols)
00627 {
00628         mpaszResults = paszResults;
00629         mnRows = nRows;
00630         mnCols = nCols;
00631         mnCurrentRow = 0;
00632 }
00633 
00634 
00635 CppSQLite3Table::~CppSQLite3Table()
00636 {
00637         try
00638         {
00639                 finalize();
00640         }
00641         catch (...)
00642         {
00643         }
00644 }
00645 
00646 
00647 CppSQLite3Table& CppSQLite3Table::operator=(const CppSQLite3Table& rTable)
00648 {
00649         try
00650         {
00651                 finalize();
00652         }
00653         catch (...)
00654         {
00655         }
00656         mpaszResults = rTable.mpaszResults;
00657         // Only one object can own the results
00658         const_cast<CppSQLite3Table&>(rTable).mpaszResults = 0;
00659         mnRows = rTable.mnRows;
00660         mnCols = rTable.mnCols;
00661         mnCurrentRow = rTable.mnCurrentRow;
00662         return *this;
00663 }
00664 
00665 
00666 void CppSQLite3Table::finalize()
00667 {
00668         if (mpaszResults)
00669         {
00670                 sqlite3_free_table(mpaszResults);
00671                 mpaszResults = 0;
00672         }
00673 }
00674 
00675 
00676 int CppSQLite3Table::numFields()
00677 {
00678         checkResults();
00679         return mnCols;
00680 }
00681 
00682 
00683 int CppSQLite3Table::numRows()
00684 {
00685         checkResults();
00686         return mnRows;
00687 }
00688 
00689 
00690 const char* CppSQLite3Table::fieldValue(int nField)
00691 {
00692         checkResults();
00693 
00694         if (nField < 0 || nField > mnCols-1)
00695         {
00696                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00697                                                                 "Invalid field index requested",
00698                                                                 DONT_DELETE_MSG);
00699         }
00700 
00701         int nIndex = (mnCurrentRow*mnCols) + mnCols + nField;
00702         return mpaszResults[nIndex];
00703 }
00704 
00705 
00706 const char* CppSQLite3Table::fieldValue(const char* szField)
00707 {
00708         checkResults();
00709 
00710         if (szField)
00711         {
00712                 for (int nField = 0; nField < mnCols; nField++)
00713                 {
00714                         if (strcmp(szField, mpaszResults[nField]) == 0)
00715                         {
00716                                 int nIndex = (mnCurrentRow*mnCols) + mnCols + nField;
00717                                 return mpaszResults[nIndex];
00718                         }
00719                 }
00720         }
00721 
00722         throw CppSQLite3Exception(CPPSQLITE_ERROR,
00723                                                         "Invalid field name requested",
00724                                                         DONT_DELETE_MSG);
00725 }
00726 
00727 
00728 int CppSQLite3Table::getIntField(int nField, int nNullValue/*=0*/)
00729 {
00730         if (fieldIsNull(nField))
00731         {
00732                 return nNullValue;
00733         }
00734         else
00735         {
00736                 return atoi(fieldValue(nField));
00737         }
00738 }
00739 
00740 
00741 int CppSQLite3Table::getIntField(const char* szField, int nNullValue/*=0*/)
00742 {
00743         if (fieldIsNull(szField))
00744         {
00745                 return nNullValue;
00746         }
00747         else
00748         {
00749                 return atoi(fieldValue(szField));
00750         }
00751 }
00752 
00753 
00754 double CppSQLite3Table::getFloatField(int nField, double fNullValue/*=0.0*/)
00755 {
00756         if (fieldIsNull(nField))
00757         {
00758                 return fNullValue;
00759         }
00760         else
00761         {
00762                 return atof(fieldValue(nField));
00763         }
00764 }
00765 
00766 
00767 double CppSQLite3Table::getFloatField(const char* szField, double fNullValue/*=0.0*/)
00768 {
00769         if (fieldIsNull(szField))
00770         {
00771                 return fNullValue;
00772         }
00773         else
00774         {
00775                 return atof(fieldValue(szField));
00776         }
00777 }
00778 
00779 
00780 const char* CppSQLite3Table::getStringField(int nField, const char* szNullValue/*=""*/)
00781 {
00782         if (fieldIsNull(nField))
00783         {
00784                 return szNullValue;
00785         }
00786         else
00787         {
00788                 return fieldValue(nField);
00789         }
00790 }
00791 
00792 
00793 const char* CppSQLite3Table::getStringField(const char* szField, const char* szNullValue/*=""*/)
00794 {
00795         if (fieldIsNull(szField))
00796         {
00797                 return szNullValue;
00798         }
00799         else
00800         {
00801                 return fieldValue(szField);
00802         }
00803 }
00804 
00805 
00806 bool CppSQLite3Table::fieldIsNull(int nField)
00807 {
00808         checkResults();
00809         return (fieldValue(nField) == 0);
00810 }
00811 
00812 
00813 bool CppSQLite3Table::fieldIsNull(const char* szField)
00814 {
00815         checkResults();
00816         return (fieldValue(szField) == 0);
00817 }
00818 
00819 
00820 const char* CppSQLite3Table::fieldName(int nCol)
00821 {
00822         checkResults();
00823 
00824         if (nCol < 0 || nCol > mnCols-1)
00825         {
00826                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00827                                                                 "Invalid field index requested",
00828                                                                 DONT_DELETE_MSG);
00829         }
00830 
00831         return mpaszResults[nCol];
00832 }
00833 
00834 
00835 void CppSQLite3Table::setRow(int nRow)
00836 {
00837         checkResults();
00838 
00839         if (nRow < 0 || nRow > mnRows-1)
00840         {
00841                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00842                                                                 "Invalid row index requested",
00843                                                                 DONT_DELETE_MSG);
00844         }
00845 
00846         mnCurrentRow = nRow;
00847 }
00848 
00849 
00850 void CppSQLite3Table::checkResults()
00851 {
00852         if (mpaszResults == 0)
00853         {
00854                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
00855                                                                 "Null Results pointer",
00856                                                                 DONT_DELETE_MSG);
00857         }
00858 }
00859 
00860 
00862 
00863 CppSQLite3Statement::CppSQLite3Statement()
00864 {
00865         mpDB = 0;
00866         mpVM = 0;
00867 }
00868 
00869 
00870 CppSQLite3Statement::CppSQLite3Statement(const CppSQLite3Statement& rStatement)
00871 {
00872         mpDB = rStatement.mpDB;
00873         mpVM = rStatement.mpVM;
00874         // Only one object can own VM
00875         const_cast<CppSQLite3Statement&>(rStatement).mpVM = 0;
00876 }
00877 
00878 
00879 CppSQLite3Statement::CppSQLite3Statement(sqlite3* pDB, sqlite3_stmt* pVM)
00880 {
00881         mpDB = pDB;
00882         mpVM = pVM;
00883 }
00884 
00885 
00886 CppSQLite3Statement::~CppSQLite3Statement()
00887 {
00888         try
00889         {
00890                 finalize();
00891         }
00892         catch (...)
00893         {
00894         }
00895 }
00896 
00897 
00898 CppSQLite3Statement& CppSQLite3Statement::operator=(const CppSQLite3Statement& rStatement)
00899 {
00900         mpDB = rStatement.mpDB;
00901         mpVM = rStatement.mpVM;
00902         // Only one object can own VM
00903         const_cast<CppSQLite3Statement&>(rStatement).mpVM = 0;
00904         return *this;
00905 }
00906 
00907 
00908 int CppSQLite3Statement::execDML()
00909 {
00910         checkDB();
00911         checkVM();
00912 
00913         const char* szError=0;
00914 
00915         int nRet = sqlite3_step(mpVM);
00916 
00917         if (nRet == SQLITE_DONE)
00918         {
00919                 int nRowsChanged = sqlite3_changes(mpDB);
00920 
00921                 nRet = sqlite3_reset(mpVM);
00922 
00923                 if (nRet != SQLITE_OK)
00924                 {
00925                         szError = sqlite3_errmsg(mpDB);
00926                         throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
00927                 }
00928 
00929                 return nRowsChanged;
00930         }
00931         else
00932         {
00933                 nRet = sqlite3_reset(mpVM);
00934                 szError = sqlite3_errmsg(mpDB);
00935                 throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
00936         }
00937 }
00938 
00939 
00940 CppSQLite3Query CppSQLite3Statement::execQuery()
00941 {
00942         checkDB();
00943         checkVM();
00944 
00945         int nRet = sqlite3_step(mpVM);
00946 
00947         if (nRet == SQLITE_DONE)
00948         {
00949                 // no rows
00950                 return CppSQLite3Query(mpDB, mpVM, true/*eof*/, false);
00951         }
00952         else if (nRet == SQLITE_ROW)
00953         {
00954                 // at least 1 row
00955                 return CppSQLite3Query(mpDB, mpVM, false/*eof*/, false);
00956         }
00957         else
00958         {
00959                 nRet = sqlite3_reset(mpVM);
00960                 const char* szError = sqlite3_errmsg(mpDB);
00961                 throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
00962         }
00963 }
00964 
00965 
00966 void CppSQLite3Statement::bind(int nParam, const char* szValue)
00967 {
00968         checkVM();
00969         int nRes = sqlite3_bind_text(mpVM, nParam, szValue, -1, SQLITE_TRANSIENT);
00970 
00971         if (nRes != SQLITE_OK)
00972         {
00973                 throw CppSQLite3Exception(nRes,
00974                                                                 "Error binding string param",
00975                                                                 DONT_DELETE_MSG);
00976         }
00977 }
00978 
00979 
00980 void CppSQLite3Statement::bind(int nParam, const int nValue)
00981 {
00982         checkVM();
00983         int nRes = sqlite3_bind_int(mpVM, nParam, nValue);
00984 
00985         if (nRes != SQLITE_OK)
00986         {
00987                 throw CppSQLite3Exception(nRes,
00988                                                                 "Error binding int param",
00989                                                                 DONT_DELETE_MSG);
00990         }
00991 }
00992 
00993 
00994 void CppSQLite3Statement::bind(int nParam, const double dValue)
00995 {
00996         checkVM();
00997         int nRes = sqlite3_bind_double(mpVM, nParam, dValue);
00998 
00999         if (nRes != SQLITE_OK)
01000         {
01001                 throw CppSQLite3Exception(nRes,
01002                                                                 "Error binding double param",
01003                                                                 DONT_DELETE_MSG);
01004         }
01005 }
01006 
01007 
01008 void CppSQLite3Statement::bind(int nParam, const unsigned char* blobValue, int nLen)
01009 {
01010         checkVM();
01011         int nRes = sqlite3_bind_blob(mpVM, nParam,
01012                                                                 (const void*)blobValue, nLen, SQLITE_TRANSIENT);
01013 
01014         if (nRes != SQLITE_OK)
01015         {
01016                 throw CppSQLite3Exception(nRes,
01017                                                                 "Error binding blob param",
01018                                                                 DONT_DELETE_MSG);
01019         }
01020 }
01021 
01022         
01023 void CppSQLite3Statement::bindNull(int nParam)
01024 {
01025         checkVM();
01026         int nRes = sqlite3_bind_null(mpVM, nParam);
01027 
01028         if (nRes != SQLITE_OK)
01029         {
01030                 throw CppSQLite3Exception(nRes,
01031                                                                 "Error binding NULL param",
01032                                                                 DONT_DELETE_MSG);
01033         }
01034 }
01035 
01036 
01037 void CppSQLite3Statement::reset()
01038 {
01039         if (mpVM)
01040         {
01041                 int nRet = sqlite3_reset(mpVM);
01042 
01043                 if (nRet != SQLITE_OK)
01044                 {
01045                         const char* szError = sqlite3_errmsg(mpDB);
01046                         throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
01047                 }
01048         }
01049 }
01050 
01051 
01052 void CppSQLite3Statement::finalize()
01053 {
01054         if (mpVM)
01055         {
01056                 int nRet = sqlite3_finalize(mpVM);
01057                 mpVM = 0;
01058 
01059                 if (nRet != SQLITE_OK)
01060                 {
01061                         const char* szError = sqlite3_errmsg(mpDB);
01062                         throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
01063                 }
01064         }
01065 }
01066 
01067 
01068 void CppSQLite3Statement::checkDB()
01069 {
01070         if (mpDB == 0)
01071         {
01072                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
01073                                                                 "Database not open",
01074                                                                 DONT_DELETE_MSG);
01075         }
01076 }
01077 
01078 
01079 void CppSQLite3Statement::checkVM()
01080 {
01081         if (mpVM == 0)
01082         {
01083                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
01084                                                                 "Null Virtual Machine pointer",
01085                                                                 DONT_DELETE_MSG);
01086         }
01087 }
01088 
01089 
01091 
01092 CppSQLite3DB::CppSQLite3DB()
01093 {
01094         mpDB = 0;
01095         mnBusyTimeoutMs = 60000; // 60 seconds
01096 }
01097 
01098 
01099 CppSQLite3DB::CppSQLite3DB(const CppSQLite3DB& db)
01100 {
01101         mpDB = db.mpDB;
01102         mnBusyTimeoutMs = 60000; // 60 seconds
01103 }
01104 
01105 
01106 CppSQLite3DB::~CppSQLite3DB()
01107 {
01108         close();
01109 }
01110 
01111 
01112 CppSQLite3DB& CppSQLite3DB::operator=(const CppSQLite3DB& db)
01113 {
01114         mpDB = db.mpDB;
01115         mnBusyTimeoutMs = 60000; // 60 seconds
01116         return *this;
01117 }
01118 
01119 
01120 void CppSQLite3DB::open(const char* szFile)
01121 {
01122         int nRet = sqlite3_open(szFile, &mpDB);
01123 
01124         if (nRet != SQLITE_OK)
01125         {
01126                 const char* szError = sqlite3_errmsg(mpDB);
01127                 throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
01128         }
01129 
01130         setBusyTimeout(mnBusyTimeoutMs);
01131 }
01132 
01133 
01134 void CppSQLite3DB::close()
01135 {
01136         if (mpDB)
01137         {
01138                 sqlite3_close(mpDB);
01139                 mpDB = 0;
01140         }
01141 }
01142 
01143 
01144 CppSQLite3Statement CppSQLite3DB::compileStatement(const char* szSQL)
01145 {
01146         checkDB();
01147 
01148         sqlite3_stmt* pVM = compile(szSQL);
01149         return CppSQLite3Statement(mpDB, pVM);
01150 }
01151 
01152 
01153 bool CppSQLite3DB::tableExists(const char* szTable)
01154 {
01155         char szSQL[128];
01156         sprintf(szSQL,
01157                         "select count(*) from sqlite_master where type='table' and name='%s'",
01158                         szTable);
01159         int nRet = execScalar(szSQL);
01160         return (nRet > 0);
01161 }
01162 
01163 
01164 int CppSQLite3DB::execDML(const char* szSQL)
01165 {
01166         checkDB();
01167 
01168         char* szError=0;
01169 
01170         int nRet = sqlite3_exec(mpDB, szSQL, 0, 0, &szError);
01171 
01172         if (nRet == SQLITE_OK)
01173         {
01174                 return sqlite3_changes(mpDB);
01175         }
01176         else
01177         {
01178                 throw CppSQLite3Exception(nRet, szError);
01179         }
01180 }
01181 
01182 
01183 CppSQLite3Query CppSQLite3DB::execQuery(const char* szSQL)
01184 {
01185         checkDB();
01186 
01187         sqlite3_stmt* pVM = compile(szSQL);
01188 
01189         int nRet = sqlite3_step(pVM);
01190 
01191         if (nRet == SQLITE_DONE)
01192         {
01193                 // no rows
01194                 return CppSQLite3Query(mpDB, pVM, true/*eof*/);
01195         }
01196         else if (nRet == SQLITE_ROW)
01197         {
01198                 // at least 1 row
01199                 return CppSQLite3Query(mpDB, pVM, false/*eof*/);
01200         }
01201         else
01202         {
01203                 nRet = sqlite3_finalize(pVM);
01204                 const char* szError= sqlite3_errmsg(mpDB);
01205                 throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
01206         }
01207 }
01208 
01209 
01210 int CppSQLite3DB::execScalar(const char* szSQL)
01211 {
01212         CppSQLite3Query q = execQuery(szSQL);
01213 
01214         if (q.eof() || q.numFields() < 1)
01215         {
01216                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
01217                                                                 "Invalid scalar query",
01218                                                                 DONT_DELETE_MSG);
01219         }
01220 
01221         return atoi(q.fieldValue(0));
01222 }
01223 
01224 
01225 CppSQLite3Table CppSQLite3DB::getTable(const char* szSQL)
01226 {
01227         checkDB();
01228 
01229         char* szError=0;
01230         char** paszResults=0;
01231         int nRet;
01232         int nRows(0);
01233         int nCols(0);
01234 
01235         nRet = sqlite3_get_table(mpDB, szSQL, &paszResults, &nRows, &nCols, &szError);
01236 
01237         if (nRet == SQLITE_OK)
01238         {
01239                 return CppSQLite3Table(paszResults, nRows, nCols);
01240         }
01241         else
01242         {
01243                 throw CppSQLite3Exception(nRet, szError);
01244         }
01245 }
01246 
01247 
01248 sqlite_int64 CppSQLite3DB::lastRowId()
01249 {
01250         return sqlite3_last_insert_rowid(mpDB);
01251 }
01252 
01253 
01254 void CppSQLite3DB::setBusyTimeout(int nMillisecs)
01255 {
01256         mnBusyTimeoutMs = nMillisecs;
01257         sqlite3_busy_timeout(mpDB, mnBusyTimeoutMs);
01258 }
01259 
01260 
01261 void CppSQLite3DB::checkDB()
01262 {
01263         if (!mpDB)
01264         {
01265                 throw CppSQLite3Exception(CPPSQLITE_ERROR,
01266                                                                 "Database not open",
01267                                                                 DONT_DELETE_MSG);
01268         }
01269 }
01270 
01271 
01272 sqlite3_stmt* CppSQLite3DB::compile(const char* szSQL)
01273 {
01274         checkDB();
01275 
01276         char* szError=0;
01277         const char* szTail=0;
01278         sqlite3_stmt* pVM;
01279 
01280         int nRet = sqlite3_prepare(mpDB, szSQL, -1, &pVM, &szTail);
01281 
01282         if (nRet != SQLITE_OK)
01283         {
01284                 throw CppSQLite3Exception(nRet, szError);
01285         }
01286 
01287         return pVM;
01288 }
01289 
01290 
01292 // SQLite encode.c reproduced here, containing implementation notes and source
01293 // for sqlite3_encode_binary() and sqlite3_decode_binary() 
01295 
01296 /*
01297 ** 2002 April 25
01298 **
01299 ** The author disclaims copyright to this source code.  In place of
01300 ** a legal notice, here is a blessing:
01301 **
01302 **    May you do good and not evil.
01303 **    May you find forgiveness for yourself and forgive others.
01304 **    May you share freely, never taking more than you give.
01305 **
01306 *************************************************************************
01307 ** This file contains helper routines used to translate binary data into
01308 ** a null-terminated string (suitable for use in SQLite) and back again.
01309 ** These are convenience routines for use by people who want to store binary
01310 ** data in an SQLite database.  The code in this file is not used by any other
01311 ** part of the SQLite library.
01312 **
01313 ** $Id: encode.c,v 1.10 2004/01/14 21:59:23 drh Exp $
01314 */
01315 
01316 /*
01317 ** How This Encoder Works
01318 **
01319 ** The output is allowed to contain any character except 0x27 (') and
01320 ** 0x00.  This is accomplished by using an escape character to encode
01321 ** 0x27 and 0x00 as a two-byte sequence.  The escape character is always
01322 ** 0x01.  An 0x00 is encoded as the two byte sequence 0x01 0x01.  The
01323 ** 0x27 character is encoded as the two byte sequence 0x01 0x03.  Finally,
01324 ** the escape character itself is encoded as the two-character sequence
01325 ** 0x01 0x02.
01326 **
01327 ** To summarize, the encoder works by using an escape sequences as follows:
01328 **
01329 **       0x00  ->  0x01 0x01
01330 **       0x01  ->  0x01 0x02
01331 **       0x27  ->  0x01 0x03
01332 **
01333 ** If that were all the encoder did, it would work, but in certain cases
01334 ** it could double the size of the encoded string.  For example, to
01335 ** encode a string of 100 0x27 characters would require 100 instances of
01336 ** the 0x01 0x03 escape sequence resulting in a 200-character output.
01337 ** We would prefer to keep the size of the encoded string smaller than
01338 ** this.
01339 **
01340 ** To minimize the encoding size, we first add a fixed offset value to each 
01341 ** byte in the sequence.  The addition is modulo 256.  (That is to say, if
01342 ** the sum of the original character value and the offset exceeds 256, then
01343 ** the higher order bits are truncated.)  The offset is chosen to minimize
01344 ** the number of characters in the string that need to be escaped.  For
01345 ** example, in the case above where the string was composed of 100 0x27
01346 ** characters, the offset might be 0x01.  Each of the 0x27 characters would
01347 ** then be converted into an 0x28 character which would not need to be
01348 ** escaped at all and so the 100 character input string would be converted
01349 ** into just 100 characters of output.  Actually 101 characters of output - 
01350 ** we have to record the offset used as the first byte in the sequence so
01351 ** that the string can be decoded.  Since the offset value is stored as
01352 ** part of the output string and the output string is not allowed to contain
01353 ** characters 0x00 or 0x27, the offset cannot be 0x00 or 0x27.
01354 **
01355 ** Here, then, are the encoding steps:
01356 **
01357 **     (1)   Choose an offset value and make it the first character of
01358 **           output.
01359 **
01360 **     (2)   Copy each input character into the output buffer, one by
01361 **           one, adding the offset value as you copy.
01362 **
01363 **     (3)   If the value of an input character plus offset is 0x00, replace
01364 **           that one character by the two-character sequence 0x01 0x01.
01365 **           If the sum is 0x01, replace it with 0x01 0x02.  If the sum
01366 **           is 0x27, replace it with 0x01 0x03.
01367 **
01368 **     (4)   Put a 0x00 terminator at the end of the output.
01369 **
01370 ** Decoding is obvious:
01371 **
01372 **     (5)   Copy encoded characters except the first into the decode 
01373 **           buffer.  Set the first encoded character aside for use as
01374 **           the offset in step 7 below.
01375 **
01376 **     (6)   Convert each 0x01 0x01 sequence into a single character 0x00.
01377 **           Convert 0x01 0x02 into 0x01.  Convert 0x01 0x03 into 0x27.
01378 **
01379 **     (7)   Subtract the offset value that was the first character of
01380 **           the encoded buffer from all characters in the output buffer.
01381 **
01382 ** The only tricky part is step (1) - how to compute an offset value to
01383 ** minimize the size of the output buffer.  This is accomplished by testing
01384 ** all offset values and picking the one that results in the fewest number
01385 ** of escapes.  To do that, we first scan the entire input and count the
01386 ** number of occurances of each character value in the input.  Suppose
01387 ** the number of 0x00 characters is N(0), the number of occurances of 0x01
01388 ** is N(1), and so forth up to the number of occurances of 0xff is N(255).
01389 ** An offset of 0 is not allowed so we don't have to test it.  The number
01390 ** of escapes required for an offset of 1 is N(1)+N(2)+N(40).  The number
01391 ** of escapes required for an offset of 2 is N(2)+N(3)+N(41).  And so forth.
01392 ** In this way we find the offset that gives the minimum number of escapes,
01393 ** and thus minimizes the length of the output string.
01394 */
01395 
01396 /*
01397 ** Encode a binary buffer "in" of size n bytes so that it contains
01398 ** no instances of characters '\'' or '\000'.  The output is 
01399 ** null-terminated and can be used as a string value in an INSERT
01400 ** or UPDATE statement.  Use sqlite3_decode_binary() to convert the
01401 ** string back into its original binary.
01402 **
01403 ** The result is written into a preallocated output buffer "out".
01404 ** "out" must be able to hold at least 2 +(257*n)/254 bytes.
01405 ** In other words, the output will be expanded by as much as 3
01406 ** bytes for every 254 bytes of input plus 2 bytes of fixed overhead.
01407 ** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.)
01408 **
01409 ** The return value is the number of characters in the encoded
01410 ** string, excluding the "\000" terminator.
01411 */
01412 int sqlite3_encode_binary(const unsigned char *in, int n, unsigned char *out){
01413   int i, j, e, m;
01414   int cnt[256];
01415   if( n<=0 ){
01416     out[0] = 'x';
01417     out[1] = 0;
01418     return 1;
01419   }
01420   memset(cnt, 0, sizeof(cnt));
01421   for(i=n-1; i>=0; i--){ cnt[in[i]]++; }
01422   m = n;
01423   for(i=1; i<256; i++){
01424     int sum;
01425     if( i=='\'' ) continue;
01426     sum = cnt[i] + cnt[(i+1)&0xff] + cnt[(i+'\'')&0xff];
01427     if( sum<m ){
01428       m = sum;
01429       e = i;
01430       if( m==0 ) break;
01431     }
01432   }
01433   out[0] = e;
01434   j = 1;
01435   for(i=0; i<n; i++){
01436     int c = (in[i] - e)&0xff;
01437     if( c==0 ){
01438       out[j++] = 1;
01439       out[j++] = 1;
01440     }else if( c==1 ){
01441       out[j++] = 1;
01442       out[j++] = 2;
01443     }else if( c=='\'' ){
01444       out[j++] = 1;
01445       out[j++] = 3;
01446     }else{
01447       out[j++] = c;
01448     }
01449   }
01450   out[j] = 0;
01451   return j;
01452 }
01453 
01454 /*
01455 ** Decode the string "in" into binary data and write it into "out".
01456 ** This routine reverses the encoding created by sqlite3_encode_binary().
01457 ** The output will always be a few bytes less than the input.  The number
01458 ** of bytes of output is returned.  If the input is not a well-formed
01459 ** encoding, -1 is returned.
01460 **
01461 ** The "in" and "out" parameters may point to the same buffer in order
01462 ** to decode a string in place.
01463 */
01464 int sqlite3_decode_binary(const unsigned char *in, unsigned char *out){
01465   int i, c, e;
01466   e = *(in++);
01467   i = 0;
01468   while( (c = *(in++))!=0 ){
01469     if( c==1 ){
01470       c = *(in++);
01471       if( c==1 ){
01472         c = 0;
01473       }else if( c==2 ){
01474         c = 1;
01475       }else if( c==3 ){
01476         c = '\'';
01477       }else{
01478         return -1;
01479       }
01480     }
01481     out[i++] = (c + e)&0xff;
01482   }
01483   return i;
01484 }

Generated on Mon Dec 3 04:30:13 2007 for lo-testserver by  doxygen 1.3.9.1