CppSQLite3U.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. ////////////////////////////////////////////////////////////////////////////////
  2. // CppSQLite3U is a C++ unicode wrapper around the SQLite3 embedded database library.
  3. //
  4. // Copyright (c) 2006 Tyushkov Nikolay. All Rights Reserved. http://softvoile.com
  5. //
  6. //
  7. // Based on beautiful wrapper written by Rob Groves
  8. // (https://secure.codeproject.com/database/CppSQLite.asp).
  9. // Very good wrapper, but without unicode support unfortunately.
  10. // So, I have reconstructed it for unicode.
  11. //
  12. // CppSQLite3 wrapper:
  13. // Copyright (c) 2004 Rob Groves. All Rights Reserved. rob.groves@btinternet.com
  14. //
  15. // Permission to use, copy, modify, and distribute this software and its
  16. // documentation for any purpose, without fee, and without a written
  17. // agreement, is hereby granted, provided that the above copyright notice,
  18. // this paragraph and the following two paragraphs appear in all copies,
  19. // modifications, and distributions.
  20. //
  21. // IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
  22. // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
  23. // PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
  24. // EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. //
  26. // THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
  27. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  28. // PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
  29. // ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION
  30. // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  31. //
  32. // If you want to get some documentation look at
  33. // https://secure.codeproject.com/database/CppSQLite.asp
  34. // Note, not all features from CppSQLite3 were implemented in CppSQLite3U
  35. //
  36. // V1.0 11/06/2006 - Initial Public Version
  37. //
  38. // Notes :
  39. // I have tested this wrapper only in unicode version, so I have no idea
  40. // about its work in ANSI configuration, I think it doesn't work without modification;)
  41. //
  42. // Home page : http://softvoile.com/development/CppSQLite3U/
  43. // Please send all bug report and comment to mail2@softvoile.com
  44. //
  45. //
  46. ////////////////////////////////////////////////////////////////////////////////
  47. #include "stdafx.h"
  48. #include "CppSQLite3U.h"
  49. #ifdef _DEBUG
  50. #define new DEBUG_NEW
  51. #undef THIS_FILE
  52. static char THIS_FILE[] = __FILE__;
  53. #endif
  54. namespace OTSSQLITE
  55. {
  56. /////////////////////////////////////////////////////////////////////////////
  57. // CppSQLite3Exception
  58. CppSQLite3Exception::CppSQLite3Exception(const int nErrCode,
  59. LPTSTR a_sErrMess,
  60. bool a_bDeleteMsg/*=true*/)
  61. : m_nErrCode(nErrCode)
  62. {
  63. m_sErrMessage.Format(_T("%s[%d]: %s"), GetErrorCodeAsString(nErrCode), nErrCode, a_sErrMess ? a_sErrMess : _T(""));
  64. if (a_bDeleteMsg && a_sErrMess)
  65. {
  66. _sqlite3_free((char*)a_sErrMess);
  67. }
  68. }
  69. CppSQLite3Exception::CppSQLite3Exception(const CppSQLite3Exception& ex)
  70. : m_nErrCode(ex.m_nErrCode)
  71. , m_sErrMessage(ex.m_sErrMessage)
  72. {
  73. }
  74. LPCTSTR CppSQLite3Exception::GetErrorCodeAsString(int a_nErrCode)
  75. {
  76. switch (a_nErrCode)
  77. {
  78. case SQLITE_OK : return _T("SQLITE_OK");
  79. case SQLITE_ERROR : return _T("SQLITE_ERROR");
  80. case SQLITE_INTERNAL : return _T("SQLITE_INTERNAL");
  81. case SQLITE_PERM : return _T("SQLITE_PERM");
  82. case SQLITE_ABORT : return _T("SQLITE_ABORT");
  83. case SQLITE_BUSY : return _T("SQLITE_BUSY");
  84. case SQLITE_LOCKED : return _T("SQLITE_LOCKED");
  85. case SQLITE_NOMEM : return _T("SQLITE_NOMEM");
  86. case SQLITE_READONLY : return _T("SQLITE_READONLY");
  87. case SQLITE_INTERRUPT : return _T("SQLITE_INTERRUPT");
  88. case SQLITE_IOERR : return _T("SQLITE_IOERR");
  89. case SQLITE_CORRUPT : return _T("SQLITE_CORRUPT");
  90. case SQLITE_NOTFOUND : return _T("SQLITE_NOTFOUND");
  91. case SQLITE_FULL : return _T("SQLITE_FULL");
  92. case SQLITE_CANTOPEN : return _T("SQLITE_CANTOPEN");
  93. case SQLITE_PROTOCOL : return _T("SQLITE_PROTOCOL");
  94. case SQLITE_EMPTY : return _T("SQLITE_EMPTY");
  95. case SQLITE_SCHEMA : return _T("SQLITE_SCHEMA");
  96. case SQLITE_TOOBIG : return _T("SQLITE_TOOBIG");
  97. case SQLITE_CONSTRAINT : return _T("SQLITE_CONSTRAINT");
  98. case SQLITE_MISMATCH : return _T("SQLITE_MISMATCH");
  99. case SQLITE_MISUSE : return _T("SQLITE_MISUSE");
  100. case SQLITE_NOLFS : return _T("SQLITE_NOLFS");
  101. case SQLITE_AUTH : return _T("SQLITE_AUTH");
  102. case SQLITE_FORMAT : return _T("SQLITE_FORMAT");
  103. case SQLITE_RANGE : return _T("SQLITE_RANGE");
  104. case SQLITE_ROW : return _T("SQLITE_ROW");
  105. case SQLITE_DONE : return _T("SQLITE_DONE");
  106. case CPPSQLITE_ERROR : return _T("CPPSQLITE_ERROR");
  107. default: return _T("UNKNOWN_ERROR");
  108. }
  109. }
  110. CppSQLite3Exception::~CppSQLite3Exception()
  111. {
  112. }
  113. /////////////////////////////////////////////////////////////////////////////
  114. // CppSQLite3DB
  115. CppSQLite3DB::CppSQLite3DB()
  116. {
  117. m_pDB = 0;
  118. m_nBusyTimeoutMs = 60000; // 60 seconds
  119. }
  120. CppSQLite3DB::CppSQLite3DB(const CppSQLite3DB& db)
  121. {
  122. m_pDB = db.m_pDB;
  123. m_nBusyTimeoutMs = 60000; // 60 seconds
  124. }
  125. CppSQLite3DB::~CppSQLite3DB()
  126. {
  127. close();
  128. }
  129. ////////////////////////////////////////////////////////////////////////////////
  130. CppSQLite3DB& CppSQLite3DB::operator=(const CppSQLite3DB& db)
  131. {
  132. m_pDB = db.m_pDB;
  133. m_nBusyTimeoutMs = 60000; // 60 seconds
  134. return *this;
  135. }
  136. void CppSQLite3DB::open(LPCTSTR szFile)
  137. {
  138. int nRet;
  139. #if defined(_UNICODE) || defined(UNICODE)
  140. nRet = sqlite3_open16(szFile, &m_pDB); // not tested under window 98
  141. #else // For Ansi Version
  142. //*************- Added by Begemot szFile must be in unicode- 23/03/06 11:04 - ****
  143. /* OSVERSIONINFOEX osvi;
  144. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  145. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  146. GetVersionEx ((OSVERSIONINFO *) &osvi);
  147. if ( osvi.dwMajorVersion == 5)
  148. {
  149. WCHAR pMultiByteStr[MAX_PATH+1];
  150. MultiByteToWideChar( CP_ACP, 0, szFile,
  151. _tcslen(szFile)+1, pMultiByteStr,
  152. sizeof(pMultiByteStr)/sizeof(pMultiByteStr[0]) );
  153. nRet = sqlite3_open16(pMultiByteStr, &m_pDB);
  154. }
  155. else*/
  156. //Îļþ·¾¶µÄ±àÂëת»» translate the file path encoding to utf-8 .added by gsp 2019-12-18
  157. int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
  158. int nlen = MultiByteToWideChar(codepage, 0, szFile, -1, NULL, 0);
  159. WCHAR wBuf[256];
  160. MultiByteToWideChar(CP_ACP, 0, szFile, -1, wBuf, nlen);
  161. CHAR pBuf[256];
  162. nlen = WideCharToMultiByte(CP_UTF8, 0, wBuf, -1, 0, 0, 0, 0);
  163. WideCharToMultiByte(CP_UTF8, 0, wBuf, -1, pBuf, nlen, 0, 0);
  164. nRet = sqlite3_open(pBuf, &m_pDB);
  165. #endif
  166. //*************************
  167. if (nRet != SQLITE_OK)
  168. {
  169. LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDB);
  170. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  171. }
  172. setBusyTimeout(m_nBusyTimeoutMs);
  173. }
  174. bool CppSQLite3DB::isOpened()
  175. {
  176. return !!m_pDB;
  177. }
  178. void CppSQLite3DB::close()
  179. {
  180. if (m_pDB)
  181. {
  182. int nRet = _sqlite3_close(m_pDB);
  183. if (nRet != SQLITE_OK)
  184. {
  185. LPCTSTR szError = (LPCTSTR)_sqlite3_errmsg(m_pDB);
  186. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  187. }
  188. m_pDB = 0;
  189. }
  190. }
  191. CppSQLite3StatementPtr CppSQLite3DB::compileStatement(LPCTSTR szSQL)
  192. {
  193. checkDB();
  194. sqlite3_stmt* pVM = compile(szSQL);
  195. return CppSQLite3StatementPtr(new CppSQLite3Statement(shared_from_this(), pVM));
  196. }
  197. bool CppSQLite3DB::tableExists(LPCTSTR szTable)
  198. {
  199. CString sSQL;
  200. sSQL.Format(_T("select count(*) from sqlite_master where type='table' and name='%s'"), szTable);
  201. int nRet = execScalar(sSQL);
  202. return (nRet > 0);
  203. }
  204. int CppSQLite3DB::execDML(LPCTSTR szSQL)
  205. {
  206. int nRet;
  207. sqlite3_stmt* pVM;
  208. checkDB();
  209. do{
  210. pVM = compile(szSQL);
  211. nRet = _sqlite3_step(pVM);
  212. if (nRet == SQLITE_ERROR)
  213. {
  214. _sqlite3_finalize(pVM);
  215. LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDB);
  216. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  217. }
  218. nRet = _sqlite3_finalize(pVM);
  219. }
  220. while( nRet == SQLITE_SCHEMA );
  221. return nRet;
  222. }
  223. CppSQLite3QueryPtr CppSQLite3DB::execQuery(LPCTSTR szSQL)
  224. {
  225. checkDB();
  226. int nRet;
  227. sqlite3_stmt* pVM;
  228. do{
  229. pVM = compile(szSQL);
  230. nRet = _sqlite3_step(pVM);
  231. if (nRet == SQLITE_DONE)
  232. { // no rows
  233. return CppSQLite3QueryPtr(new CppSQLite3Query(shared_from_this(), pVM, true/*eof*/));
  234. }
  235. else if (nRet == SQLITE_ROW)
  236. { // at least 1 row
  237. return CppSQLite3QueryPtr(new CppSQLite3Query(shared_from_this(), pVM, false/*eof*/));
  238. }
  239. nRet = _sqlite3_finalize(pVM);
  240. }
  241. while( nRet == SQLITE_SCHEMA ); // Edit By Begemot 08/16/06 12:44:35 - read SQLite FAQ
  242. // LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDB);
  243. // throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  244. return NULL;
  245. }
  246. int CppSQLite3DB::execScalar(LPCTSTR szSQL)
  247. {
  248. auto q = execQuery(szSQL);
  249. if (NULL == q)
  250. {
  251. return -1;
  252. }
  253. if (q->eof() || q->numFields() < 1)
  254. throw CppSQLite3Exception(CPPSQLITE_ERROR, _T("Invalid scalar query"), DONT_DELETE_MSG);
  255. return q->getIntField(0);
  256. //return _tstoi(q->fieldValue(0));
  257. }
  258. // Added By Begemot, exact as execScalar but return CString 08/06/06 16:30:37
  259. CString CppSQLite3DB::execScalarStr(LPCTSTR szSQL)
  260. {
  261. auto q = execQuery(szSQL);
  262. if (q->eof() || q->numFields() < 1)
  263. throw CppSQLite3Exception(CPPSQLITE_ERROR, _T("Invalid scalar query"), DONT_DELETE_MSG);
  264. return (CString)q->getStringField(0);
  265. }
  266. sqlite_int64 CppSQLite3DB::lastRowId()
  267. {
  268. return sqlite3_last_insert_rowid(m_pDB);
  269. }
  270. void CppSQLite3DB::setBusyTimeout(int nMillisecs)
  271. {
  272. m_nBusyTimeoutMs = nMillisecs;
  273. auto nRet = sqlite3_busy_timeout(m_pDB, m_nBusyTimeoutMs);
  274. if (nRet != SQLITE_OK)
  275. {
  276. LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDB);
  277. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  278. }
  279. }
  280. void CppSQLite3DB::checkDB()
  281. {
  282. if (!m_pDB)
  283. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Database not open"), DONT_DELETE_MSG);
  284. }
  285. sqlite3_stmt* CppSQLite3DB::compile(LPCTSTR szSQL)
  286. {
  287. checkDB();
  288. sqlite3_stmt* pVM;
  289. int nRet = _sqlite3_prepare(m_pDB, szSQL, -1, &pVM, NULL);
  290. if (SQLITE_NOTADB == nRet)
  291. {
  292. return NULL;
  293. }
  294. if (nRet != SQLITE_OK)
  295. {
  296. pVM=NULL;
  297. LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDB);
  298. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  299. }
  300. return pVM;
  301. }
  302. //////////////////////// CppSQLite3Statement ///////////////////////////////////////////
  303. CppSQLite3Statement::CppSQLite3Statement()
  304. {
  305. m_pDBPtr.reset();
  306. m_pVM = 0;
  307. }
  308. CppSQLite3Statement::CppSQLite3Statement(const CppSQLite3Statement& rStatement)
  309. {
  310. m_pDBPtr = rStatement.m_pDBPtr;
  311. m_pVM = rStatement.m_pVM;
  312. // Only one object can own VM
  313. const_cast<CppSQLite3Statement&>(rStatement).m_pVM = 0;
  314. }
  315. CppSQLite3Statement::CppSQLite3Statement(CppSQLite3DBPtr a_pDB, sqlite3_stmt* pVM)
  316. {
  317. m_pDBPtr = a_pDB;
  318. m_pVM = pVM;
  319. }
  320. CppSQLite3Statement::~CppSQLite3Statement()
  321. {
  322. try
  323. {
  324. finalize();
  325. }
  326. catch (...) {}
  327. }
  328. CppSQLite3Statement& CppSQLite3Statement::operator=(const CppSQLite3Statement& rStatement)
  329. {
  330. m_pDBPtr = rStatement.m_pDBPtr;
  331. m_pVM = rStatement.m_pVM;
  332. // Only one object can own VM
  333. const_cast<CppSQLite3Statement&>(rStatement).m_pVM = 0;
  334. return *this;
  335. }
  336. int CppSQLite3Statement::execDML()
  337. {
  338. checkDB();
  339. checkVM();
  340. int nRet = sqlite3_step(m_pVM);
  341. if (nRet == SQLITE_DONE)
  342. {
  343. int nRowsChanged = sqlite3_changes(m_pDBPtr->m_pDB);
  344. nRet = sqlite3_reset(m_pVM);
  345. if (nRet != SQLITE_OK)
  346. {
  347. LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDBPtr->m_pDB);
  348. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  349. }
  350. return nRowsChanged;
  351. }
  352. else
  353. {
  354. nRet = sqlite3_reset(m_pVM);
  355. LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDBPtr->m_pDB);
  356. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  357. }
  358. }
  359. void CppSQLite3Statement::bind(int nParam, LPCTSTR szValue)
  360. {
  361. checkVM();
  362. int nRes = _sqlite3_bind_text(m_pVM, nParam, szValue, -1, SQLITE_TRANSIENT);
  363. if (nRes != SQLITE_OK)
  364. throw CppSQLite3Exception(nRes,_T("Error binding string param"), DONT_DELETE_MSG);
  365. }
  366. void CppSQLite3Statement::bind(int nParam, const int nValue)
  367. {
  368. checkVM();
  369. int nRes = sqlite3_bind_int(m_pVM, nParam, nValue);
  370. if (nRes != SQLITE_OK)
  371. throw CppSQLite3Exception(nRes,_T("Error binding int param"), DONT_DELETE_MSG);
  372. }
  373. void CppSQLite3Statement::bind(int nParam, const double dValue)
  374. {
  375. checkVM();
  376. int nRes = sqlite3_bind_double(m_pVM, nParam, dValue);
  377. if (nRes != SQLITE_OK)
  378. throw CppSQLite3Exception(nRes, _T("Error binding double param"), DONT_DELETE_MSG);
  379. }
  380. void CppSQLite3Statement::bind(int nParam, const unsigned char* blobValue, int nLen)
  381. {
  382. checkVM();
  383. int nRes = sqlite3_bind_blob(m_pVM, nParam,(const void*)blobValue, nLen, SQLITE_TRANSIENT);
  384. if (nRes != SQLITE_OK)
  385. throw CppSQLite3Exception(nRes,_T("Error binding blob param"),DONT_DELETE_MSG);
  386. }
  387. void CppSQLite3Statement::bindNull(int nParam)
  388. {
  389. checkVM();
  390. int nRes = sqlite3_bind_null(m_pVM, nParam);
  391. if (nRes != SQLITE_OK)
  392. throw CppSQLite3Exception(nRes,_T("Error binding NULL param"),DONT_DELETE_MSG);
  393. }
  394. void CppSQLite3Statement::reset()
  395. {
  396. if (m_pVM)
  397. {
  398. int nRet = sqlite3_reset(m_pVM);
  399. if (nRet != SQLITE_OK)
  400. {
  401. LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDBPtr->m_pDB);
  402. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  403. }
  404. }
  405. }
  406. void CppSQLite3Statement::finalize()
  407. {
  408. if (m_pVM)
  409. {
  410. int nRet = sqlite3_finalize(m_pVM);
  411. m_pVM = 0;
  412. if (nRet != SQLITE_OK)
  413. {
  414. LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(m_pDBPtr->m_pDB);
  415. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  416. }
  417. }
  418. }
  419. void CppSQLite3Statement::checkDB()
  420. {
  421. if (!m_pDBPtr) throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Database not open"), DONT_DELETE_MSG);
  422. }
  423. void CppSQLite3Statement::checkVM()
  424. {
  425. if (m_pVM == 0)
  426. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Null Virtual Machine pointer"), DONT_DELETE_MSG);
  427. }
  428. ///////////////////// CppSQLite3Query //////////////////////////////////////////////////
  429. CppSQLite3Query::CppSQLite3Query()
  430. {
  431. m_pVM = 0;
  432. m_bEof = true;
  433. m_nCols = 0;
  434. m_bOwnVM = false;
  435. }
  436. CppSQLite3Query::CppSQLite3Query(const CppSQLite3Query& rQuery)
  437. {
  438. m_pVM = rQuery.m_pVM;
  439. // Only one object can own the VM
  440. const_cast<CppSQLite3Query&>(rQuery).m_pVM = 0;
  441. m_bEof = rQuery.m_bEof;
  442. m_nCols = rQuery.m_nCols;
  443. m_bOwnVM = rQuery.m_bOwnVM;
  444. }
  445. CppSQLite3Query::CppSQLite3Query(CppSQLite3DBPtr pDB, sqlite3_stmt* pVM,
  446. bool bEof, bool bOwnVM/*=true*/)
  447. {
  448. m_pDBPtr = pDB;
  449. m_pVM = pVM;
  450. m_bEof = bEof;
  451. m_nCols = _sqlite3_column_count(m_pVM);
  452. m_bOwnVM = bOwnVM;
  453. }
  454. CppSQLite3Query::~CppSQLite3Query()
  455. {
  456. try
  457. {
  458. finalize();
  459. }
  460. catch (...) {}
  461. }
  462. CppSQLite3Query& CppSQLite3Query::operator=(const CppSQLite3Query& rQuery)
  463. {
  464. try
  465. {
  466. finalize();
  467. }
  468. catch (...) { }
  469. m_pVM = rQuery.m_pVM;
  470. // Only one object can own the VM
  471. const_cast<CppSQLite3Query&>(rQuery).m_pVM = 0;
  472. m_bEof = rQuery.m_bEof;
  473. m_nCols = rQuery.m_nCols;
  474. m_bOwnVM = rQuery.m_bOwnVM;
  475. return *this;
  476. }
  477. int CppSQLite3Query::numFields()
  478. {
  479. checkVM();
  480. return m_nCols;
  481. }
  482. LPCTSTR CppSQLite3Query::fieldValue(int nField)
  483. {
  484. checkVM();
  485. if (nField < 0 || nField > m_nCols-1)
  486. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Invalid field index requested"),DONT_DELETE_MSG);
  487. return (LPCTSTR)_sqlite3_column_text(m_pVM, nField);
  488. }
  489. LPCTSTR CppSQLite3Query::fieldValue(LPCTSTR szField)
  490. {
  491. int nField = fieldIndex(szField);
  492. return (LPCTSTR)_sqlite3_column_text(m_pVM, nField);
  493. }
  494. int CppSQLite3Query::getIntField(int nField, int nNullValue/*=0*/)
  495. {
  496. if (fieldDataType(nField) == SQLITE_NULL)
  497. {
  498. return nNullValue;
  499. }
  500. else
  501. {
  502. return _sqlite3_column_int(m_pVM, nField);
  503. }
  504. }
  505. int CppSQLite3Query::getIntField(LPCTSTR szField, int nNullValue/*=0*/)
  506. {
  507. int nField = fieldIndex(szField);
  508. return getIntField(nField, nNullValue);
  509. }
  510. double CppSQLite3Query::getFloatField(int nField, double fNullValue/*=0.0*/)
  511. {
  512. if (fieldDataType(nField) == SQLITE_NULL)
  513. {
  514. return fNullValue;
  515. }
  516. else
  517. {
  518. return _sqlite3_column_double(m_pVM, nField);
  519. }
  520. }
  521. double CppSQLite3Query::getFloatField(LPCTSTR szField, double fNullValue/*=0.0*/)
  522. {
  523. int nField = fieldIndex(szField);
  524. return getFloatField(nField, fNullValue);
  525. }
  526. LPCTSTR CppSQLite3Query::getStringField(int nField, LPCTSTR szNullValue/*=""*/)
  527. {
  528. if (fieldDataType(nField) == SQLITE_NULL)
  529. {
  530. return szNullValue;
  531. }
  532. else
  533. {
  534. return (LPCTSTR)_sqlite3_column_text(m_pVM, nField);
  535. }
  536. }
  537. LPCTSTR CppSQLite3Query::getStringField(LPCTSTR szField, LPCTSTR szNullValue/*=""*/)
  538. {
  539. int nField = fieldIndex(szField);
  540. return getStringField(nField, szNullValue);
  541. }
  542. const unsigned char* CppSQLite3Query::getBlobField(int nField, int& nLen)
  543. {
  544. checkVM();
  545. if (nField < 0 || nField > m_nCols-1)
  546. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Invalid field index requested"),DONT_DELETE_MSG);
  547. nLen = _sqlite3_column_bytes(m_pVM, nField);
  548. return (const unsigned char*)sqlite3_column_blob(m_pVM, nField);
  549. }
  550. const unsigned char* CppSQLite3Query::getBlobField(LPCTSTR szField, int& nLen)
  551. {
  552. int nField = fieldIndex(szField);
  553. return getBlobField(nField, nLen);
  554. }
  555. bool CppSQLite3Query::fieldIsNull(int nField)
  556. {
  557. return (fieldDataType(nField) == SQLITE_NULL);
  558. }
  559. bool CppSQLite3Query::fieldIsNull(LPCTSTR szField)
  560. {
  561. int nField = fieldIndex(szField);
  562. return (fieldDataType(nField) == SQLITE_NULL);
  563. }
  564. int CppSQLite3Query::fieldIndex(LPCTSTR szField)
  565. {
  566. checkVM();
  567. if (szField)
  568. {
  569. for (int nField = 0; nField < m_nCols; nField++)
  570. {
  571. LPCTSTR szTemp = (LPCTSTR)_sqlite3_column_name(m_pVM, nField);
  572. if (_tcscmp(szField, szTemp) == 0)
  573. {
  574. return nField;
  575. }
  576. }
  577. }
  578. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Invalid field name requested"),DONT_DELETE_MSG);
  579. }
  580. LPCTSTR CppSQLite3Query::fieldName(int nCol)
  581. {
  582. checkVM();
  583. if (nCol < 0 || nCol > m_nCols-1)
  584. {
  585. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Invalid field index requested"),DONT_DELETE_MSG);
  586. }
  587. return (LPCTSTR)_sqlite3_column_name(m_pVM, nCol);
  588. }
  589. LPCTSTR CppSQLite3Query::fieldDeclType(int nCol)
  590. {
  591. checkVM();
  592. if (nCol < 0 || nCol > m_nCols-1)
  593. {
  594. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Invalid field index requested"),DONT_DELETE_MSG);
  595. }
  596. return (LPCTSTR)_sqlite3_column_decltype(m_pVM, nCol);
  597. }
  598. int CppSQLite3Query::fieldDataType(int nCol)
  599. {
  600. checkVM();
  601. if (nCol < 0 || nCol > m_nCols-1)
  602. {
  603. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Invalid field index requested"), DONT_DELETE_MSG);
  604. }
  605. return _sqlite3_column_type(m_pVM, nCol);
  606. }
  607. bool CppSQLite3Query::eof()
  608. {
  609. checkVM();
  610. return m_bEof;
  611. }
  612. void CppSQLite3Query::nextRow()
  613. {
  614. checkVM();
  615. int nRet = _sqlite3_step(m_pVM);
  616. if (nRet == SQLITE_DONE)
  617. {
  618. // no rows
  619. m_bEof = true;
  620. }
  621. else if (nRet == SQLITE_ROW)
  622. {
  623. // more rows, nothing to do
  624. }
  625. else
  626. {
  627. nRet = _sqlite3_finalize(m_pVM);
  628. m_pVM = 0;
  629. LPCTSTR szError = (LPCTSTR)_sqlite3_errmsg(m_pDBPtr->m_pDB);
  630. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  631. }
  632. }
  633. void CppSQLite3Query::finalize()
  634. {
  635. if (m_pVM && m_bOwnVM)
  636. {
  637. int nRet = _sqlite3_finalize(m_pVM);
  638. m_pVM = 0;
  639. if (nRet != SQLITE_OK)
  640. {
  641. LPCTSTR szError = (LPCTSTR)_sqlite3_errmsg(m_pDBPtr->m_pDB);
  642. throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG);
  643. }
  644. }
  645. }
  646. void CppSQLite3Query::checkVM()
  647. {
  648. if (m_pVM == 0)
  649. {
  650. throw CppSQLite3Exception(CPPSQLITE_ERROR,_T("Null Virtual Machine pointer"),DONT_DELETE_MSG);
  651. }
  652. }
  653. ////////////////////////////////////////////////////////////////////////////////
  654. //**************************
  655. //*************- Added By Begemot - 28/02/06 20:25 - ****
  656. CString DoubleQuotes(CString in)
  657. {
  658. in.Replace(_T("\'"),_T("\'\'"));
  659. return in;
  660. }
  661. } // namespace Datastore