QueryDef.cpp
上传用户:yunnanyeer
上传日期:2007-01-03
资源大小:86k
文件大小:32k
源码类别:

数据库编程

开发平台:

Visual C++

  1. // QueryDef.cpp : Defines the initialization routines for the DLL.
  2. //
  3. #include "stdafx.h"
  4. #include <afxdllx.h>
  5. #include "QueryDef.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. static AFX_EXTENSION_MODULE QueryDefDLL = { NULL, NULL };
  12. extern "C" int APIENTRY
  13. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  14. {
  15. UNREFERENCED_PARAMETER(lpReserved);
  16. if (dwReason == DLL_PROCESS_ATTACH)
  17. {
  18. TRACE0("QUERYDEF.DLL Initializing!n");
  19. if (!AfxInitExtensionModule(QueryDefDLL, hInstance))
  20. return 0;
  21. new CDynLinkLibrary(QueryDefDLL);
  22. }
  23. else if (dwReason == DLL_PROCESS_DETACH)
  24. {
  25. TRACE0("QUERYDEF.DLL Terminating!n");
  26. AfxTermExtensionModule(QueryDefDLL);
  27. }
  28. return 1;
  29. }
  30. namespace QueryDef // use using namespace QueryDef or
  31. { // better USE_QUERYDEF macro
  32. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  33. // CQueryVariant Class
  34. //
  35. /*
  36. template <> void AFXAPI ConstructElements <QueryDef::CQueryVar>(QueryDef::CQueryVar* pNewQueryVar,int nCount)
  37. {
  38. #if defined(_DEBUG)
  39. #undef new
  40. #endif
  41. for ( int i = 0; i < nCount; i++, pNewQueryVar++ )
  42.         // call CQueryVar default constructor directly
  43.         new (pNewQueryVar) QueryDef::CQueryVar;
  44. }
  45. */
  46. void CQueryVariant::ConstructObject()
  47. {
  48. m_decPlaces = 2; // two decimal digits by default
  49. m_dateFormat = "%d/%m/%Y %H:%M"; // default date time format
  50. }
  51. CQueryVariant::CQueryVariant()
  52. {
  53. ConstructObject();
  54. m_varDB.Add(CQueryVar());
  55. }
  56. CQueryVariant::~CQueryVariant()
  57. {
  58. }
  59. CQueryVariant::CQueryVariant(LPCTSTR str)
  60. {
  61. ConstructObject();
  62. m_varDB.Add(CQueryVar(str));
  63. }
  64. CQueryVariant::CQueryVariant(int i)
  65. {
  66. ConstructObject();
  67. m_varDB.Add(CQueryVar(i));
  68. }
  69. CQueryVariant::CQueryVariant(long l)
  70. {
  71. ConstructObject();
  72. m_varDB.Add(CQueryVar(l));
  73. }
  74. CQueryVariant::CQueryVariant(short s)
  75. {
  76. ConstructObject();
  77. m_varDB.Add(CQueryVar(s));
  78. }
  79. CQueryVariant::CQueryVariant(float f)
  80. {
  81. ConstructObject();
  82. m_varDB.Add(CQueryVar(f));
  83. }
  84. CQueryVariant::CQueryVariant(double d)
  85. {
  86. ConstructObject();
  87. m_varDB.Add(CQueryVar(d));
  88. }
  89. CQueryVariant::CQueryVariant(COleDateTime& t)
  90. {
  91. ConstructObject();
  92. m_varDB.Add(CQueryVar(t));
  93. }
  94. CQueryVariant::CQueryVariant(CLongBinary& lB)
  95. {
  96. ConstructObject();
  97. m_varDB.Add(CQueryVar(lB));
  98. }
  99. // CQueryVariant conversion operators
  100. CQueryVariant::operator CString()
  101. {
  102. return (CString)(m_varDB[0]);
  103. }
  104. CQueryVariant::operator BYTE()
  105. {
  106. return (BYTE)(m_varDB[0]);
  107. }
  108. CQueryVariant::operator int()
  109. {
  110. return (int)(m_varDB[0]);
  111. }
  112. CQueryVariant::operator long()
  113. {
  114. return (long)(m_varDB[0]);
  115. }
  116. CQueryVariant::operator short()
  117. {
  118. return (short)(m_varDB[0]);
  119. }
  120. CQueryVariant::operator float()
  121. {
  122. return (float)(m_varDB[0]);
  123. }
  124. CQueryVariant::operator double()
  125. {
  126. return (double)(m_varDB[0]);
  127. }
  128. CQueryVariant::operator COleDateTime&()
  129. {
  130. return m_varDB[0].operator COleDateTime&();
  131. }
  132. CQueryVariant::operator CLongBinary&()
  133. {
  134. return (CLongBinary&)(m_varDB[0]);
  135. }
  136. CQueryVariant::operator LPCTSTR()
  137. {
  138. return (LPCTSTR)m_varDB[0];
  139. }
  140. CQueryVariant& CQueryVariant::operator=(CStringArray& src) // converts all columns to strings
  141. {
  142. src.SetSize(m_varDB.GetSize()); // make the two arrays equal length
  143. for (WORD i = 0; i < m_varDB.GetSize(); i++)
  144. src[i] = m_varDB.GetAt(i);
  145. return *this;
  146. }
  147. CQueryVar& CQueryVariant::operator[](int i)
  148. {
  149. if (i >= m_varDB.GetSize())
  150. SetSize(i+1);
  151. return m_varDB.ElementAt(i);
  152. }
  153. CQueryVariant& CQueryVariant::operator=(CQueryVariant& v)
  154. {
  155. m_decPlaces = v.m_decPlaces;
  156. m_dateFormat = v.m_dateFormat;
  157. m_varDB.SetSize(v.m_varDB.GetSize());
  158. for (WORD i = 0; i < m_varDB.GetSize(); i++)
  159. m_varDB[i] = v.m_varDB[i];
  160. return *this;
  161. }
  162. short CQueryVariant::SetDecimalDigits(short d)
  163. {
  164. short prevDecPlaces = m_decPlaces;
  165. m_decPlaces = d;
  166. for (WORD i = 0; i < m_varDB.GetSize(); i++)
  167. m_varDB[i].SetDecimalDigits(d);
  168. return prevDecPlaces;
  169. }
  170. LPCSTR CQueryVariant::SetDateFormat(LPCSTR strDateFormat)
  171. {
  172. CString oldDateFormat = m_dateFormat;
  173. m_dateFormat = strDateFormat;
  174. for (WORD i = 0; i < m_varDB.GetSize(); i++)
  175. m_varDB[i].SetDateFormat(strDateFormat);
  176. return oldDateFormat;
  177. }
  178. void CQueryVariant::SetSize(int nNewSize)
  179. {
  180. int i,nOldSize = m_varDB.GetSize();
  181. m_varDB.SetSize(nNewSize); // calls the CQueryVar constructor
  182. for (i = nOldSize; i < nNewSize; i++)
  183. {
  184. m_varDB[i].m_decPlaces = m_decPlaces;
  185. m_varDB[i].m_dateFormat = m_dateFormat;
  186. }
  187. }
  188. //////////////////////////////////////////////////////////////////////
  189. // CQueryVar Class
  190. //////////////////////////////////////////////////////////////////////
  191. void CQueryVar::ConstructObject()
  192. {
  193. m_decPlaces = 2; // two decimal digits by default
  194. m_dateFormat = "%d/%m/%Y %H:%M"; // default date time format
  195. m_allocFlags = eAllocNothing;
  196. }
  197. CQueryVar::CQueryVar()
  198. {
  199. ConstructObject();
  200. m_dwType = DBVT_NULL;
  201. }
  202. CQueryVar::~CQueryVar()
  203. { // may be marked as NULL but with
  204. if (m_dwType != DBVT_NULL) // buffers allocated due to a
  205. return; // AddNew or Edit applied on a
  206. // subsequent CQueryDef container
  207. if (m_allocFlags == eAllocString)
  208. delete m_pstring;
  209. else if (m_allocFlags == eAllocDate)
  210. delete m_pdate;
  211. else if (m_allocFlags == eAllocBinary)
  212. delete m_pbinary;
  213. }
  214. CQueryVar::CQueryVar(LPCTSTR str)
  215. {
  216. ConstructObject();
  217. m_pstring = new CString();
  218. *m_pstring = str;
  219. m_allocFlags = eAllocString;
  220. m_dwType = DBVT_STRING;
  221. }
  222. CQueryVar::CQueryVar(int i)
  223. {
  224. ConstructObject();
  225. m_dwType = DBVT_LONG;
  226. m_lVal = i;
  227. }
  228. CQueryVar::CQueryVar(long l)
  229. {
  230. ConstructObject();
  231. m_lVal = l;
  232. m_dwType = DBVT_LONG;
  233. }
  234. CQueryVar::CQueryVar(short s)
  235. {
  236. ConstructObject();
  237. m_iVal = s;
  238. m_dwType = DBVT_SHORT;
  239. }
  240. CQueryVar::CQueryVar(float f)
  241. {
  242. ConstructObject();
  243. m_fltVal = f;
  244. m_dwType = DBVT_SINGLE;
  245. }
  246. CQueryVar::CQueryVar(double d)
  247. {
  248. ConstructObject();
  249. m_dblVal = d;
  250. m_dwType = DBVT_DOUBLE;
  251. }
  252. CQueryVar::CQueryVar(COleDateTime& t)
  253. {
  254. ConstructObject();
  255. m_pdate = new TIMESTAMP_STRUCT;
  256. m_allocFlags = eAllocDate;
  257. m_pdate->year    = (SWORD)t.GetYear();
  258. m_pdate->month   = t.GetMonth();
  259. m_pdate->day     = t.GetDay();
  260. m_pdate->hour    = t.GetHour();
  261. m_pdate->minute  = t.GetMinute();
  262. m_pdate->second  = t.GetSecond();
  263. m_pdate->fraction = 0;
  264. m_dwType = DBVT_DATE;
  265. }
  266. CQueryVar::CQueryVar(CLongBinary& lB)
  267. {
  268. void* pSrc;
  269. void* pDest;
  270. ConstructObject();
  271. m_pbinary = new CLongBinary;
  272. m_allocFlags = eAllocBinary;
  273. m_pbinary->m_hData = GlobalAlloc(GMEM_MOVEABLE,lB.m_dwDataLength);
  274. pSrc  = GlobalLock(lB.m_hData);
  275. pDest = GlobalLock(m_pbinary->m_hData);
  276. memcpy(pDest,pSrc,lB.m_dwDataLength);
  277. GlobalUnlock(lB.m_hData);
  278. GlobalUnlock(m_pbinary->m_hData);
  279. m_pbinary->m_dwDataLength = lB.m_dwDataLength;
  280. m_dwType = DBVT_BINARY;
  281. }
  282. // CQueryVar changes data type
  283. void CQueryVar::ChangeDataType(int allocFlags)
  284. {
  285. if (allocFlags == m_allocFlags)
  286. return;
  287. switch (m_allocFlags)
  288. {
  289. case eAllocString:
  290. delete m_pstring;
  291. break;
  292. case eAllocDate:
  293. delete m_pdate;
  294. break;
  295. case eAllocBinary:
  296. delete m_pbinary;
  297. break;
  298. }
  299. switch (allocFlags)
  300. {
  301. case eAllocString:
  302. m_pstring = new CString;
  303. break;
  304. case eAllocDate:
  305. m_pdate = new TIMESTAMP_STRUCT;
  306. break;
  307. case eAllocBinary:
  308. m_pbinary = new CLongBinary;
  309. m_pbinary->m_dwDataLength = 0;
  310. break;
  311. }
  312. m_allocFlags = allocFlags;
  313. }
  314. // CQueryVar conversion operators
  315. CQueryVar::operator LPCTSTR()
  316. {
  317. return ToString();
  318. }
  319. LPCTSTR CQueryVar::ToString()
  320. {
  321. CString strFormat;
  322. COleDateTime d;
  323. void* pbinary;
  324. switch (m_dwType)
  325. {
  326. case DBVT_NULL:
  327. break;
  328. case DBVT_BOOL:
  329. m_convert = m_boolVal? '1' : '0';
  330. break;
  331. case DBVT_UCHAR:
  332. m_convert.Format("%c",m_chVal);
  333. break;
  334. case DBVT_SHORT:
  335. m_convert.Format("%d",m_iVal);
  336. break;
  337. case DBVT_LONG:
  338. m_convert.Format("%ld",m_lVal);
  339. break;
  340. case DBVT_SINGLE:
  341. strFormat.Format("%%.%df",m_decPlaces);
  342. m_convert.Format(strFormat,m_fltVal);
  343. break;
  344. case DBVT_DOUBLE:
  345. strFormat.Format("%%.%dlf",m_decPlaces);
  346. m_convert.Format(strFormat,m_dblVal);
  347. break;
  348. case DBVT_DATE:
  349. d = operator COleDateTime&();
  350. m_convert = d.Format(m_dateFormat);
  351. break;
  352. case DBVT_STRING:
  353. m_convert = *m_pstring;
  354. break;
  355. case DBVT_BINARY:
  356. if (m_pbinary->m_dwDataLength > MAX_SHORT) // the BLOB is converted if less
  357. throw CQueryVariant::eMemoryLimit;
  358. pbinary = GlobalLock(m_pbinary->m_hData);
  359. if (pbinary)
  360. {
  361. m_convert = ConvertToHex(pbinary,m_pbinary->m_dwDataLength);
  362. GlobalUnlock(m_pbinary->m_hData);
  363. }
  364. break;
  365. default:
  366. throw CQueryVar::eConversionError;
  367. }
  368. return m_convert;
  369. }
  370. CQueryVar::operator BYTE()
  371. {
  372. switch (m_dwType)
  373. {
  374. case DBVT_UCHAR:
  375. return m_chVal;
  376. case DBVT_BOOL:
  377. return m_boolVal;
  378. case DBVT_SHORT:
  379. return (BYTE)m_iVal;
  380. case DBVT_LONG:
  381. return (BYTE)m_lVal;
  382. default:
  383. throw CQueryVar::eConversionError;
  384. }
  385. return m_chVal;
  386. }
  387. CQueryVar::operator int()
  388. {
  389. switch (m_dwType)
  390. {
  391. case DBVT_UCHAR:
  392. return m_chVal;
  393. case DBVT_SHORT:
  394. return m_iVal;
  395. case DBVT_BOOL:
  396. return m_boolVal;
  397. case DBVT_LONG:
  398. return m_lVal;
  399. default:
  400. throw CQueryVar::eConversionError;
  401. }
  402. return m_lVal;
  403. }
  404. CQueryVar::operator long()
  405. {
  406. switch (m_dwType)
  407. {
  408. case DBVT_LONG:
  409. return m_lVal;
  410. case DBVT_UCHAR:
  411. return m_chVal;
  412. case DBVT_SHORT:
  413. return m_iVal;
  414. case DBVT_BOOL:
  415. return m_boolVal;
  416. default:
  417. throw CQueryVar::eConversionError;
  418. }
  419. return m_lVal;
  420. }
  421. CQueryVar::operator short()
  422. {
  423. switch (m_dwType)
  424. {
  425. case DBVT_UCHAR:
  426. return m_chVal;
  427. case DBVT_SHORT:
  428. return m_iVal;
  429. case DBVT_BOOL:
  430. return m_boolVal;
  431. default:
  432. throw CQueryVar::eConversionError;
  433. }
  434. return m_iVal;
  435. }
  436. CQueryVar::operator float()
  437. {
  438. switch (m_dwType)
  439. {
  440. case DBVT_UCHAR:
  441. return m_chVal;
  442. case DBVT_SHORT:
  443. return m_iVal;
  444. case DBVT_BOOL:
  445. return (float)m_boolVal;
  446. case DBVT_SINGLE:
  447. return m_fltVal;
  448. default:
  449. throw CQueryVar::eConversionError;
  450. }
  451. return m_fltVal;
  452. }
  453. CQueryVar::operator double()
  454. {
  455. switch (m_dwType)
  456. {
  457. case DBVT_LONG:
  458. return m_lVal;
  459. case DBVT_UCHAR:
  460. return m_chVal;
  461. case DBVT_SHORT:
  462. return m_iVal;
  463. case DBVT_BOOL:
  464. return m_boolVal;
  465. case DBVT_SINGLE:
  466. return m_fltVal;
  467. case DBVT_DOUBLE:
  468. return m_dblVal;
  469. default:
  470. throw CQueryVar::eConversionError;
  471. }
  472. return m_dblVal;
  473. }
  474. CQueryVar::operator void*()
  475. {
  476. switch (m_dwType)
  477. {
  478. case DBVT_NULL: // patching CQueryDef (AddNew and Edit)
  479. if (m_allocFlags == eAllocString)
  480. return (void*)m_pstring;
  481. else if (m_allocFlags == eAllocDate)
  482. return (void*)m_pdate;
  483. else if (m_allocFlags == eAllocBinary)
  484. return (void*)m_pbinary;
  485. break;
  486. case DBVT_BOOL:
  487. case DBVT_UCHAR:
  488. case DBVT_SHORT:
  489. case DBVT_LONG:
  490. case DBVT_SINGLE:
  491. case DBVT_DOUBLE:
  492. return (void*)&m_chVal;
  493. case DBVT_STRING:
  494. return (void*)m_pstring;
  495. case DBVT_DATE:
  496. return (void*)m_pdate;
  497. case DBVT_BINARY:
  498. return (void*)m_pbinary;
  499. }
  500. return (void*)&m_chVal;
  501. }
  502. CQueryVar::operator COleDateTime&()
  503. {
  504. static COleDateTime t;
  505. if (m_dwType != DBVT_DATE)
  506. throw CQueryVar::eConversionError;
  507. t.SetDateTime(m_pdate->year,m_pdate->month,m_pdate->day,m_pdate->hour,m_pdate->minute,m_pdate->second);
  508. return t;
  509. }
  510. CQueryVar::operator CLongBinary&()
  511. {
  512. if (m_dwType != DBVT_BINARY)
  513. throw CQueryVar::eConversionError;
  514. return *m_pbinary;
  515. }
  516. CQueryVar& CQueryVar::operator=(LPCTSTR str)
  517. {
  518. m_dwType = DBVT_STRING;
  519. ChangeDataType(eAllocString);
  520. *m_pstring = str;
  521. return *this;
  522. }
  523. CQueryVar& CQueryVar::operator=(UCHAR ch)
  524. {
  525. m_dwType = DBVT_UCHAR;
  526. ChangeDataType(eAllocNothing);
  527. m_chVal = ch;
  528. return *this;
  529. }
  530. CQueryVar& CQueryVar::operator=(int l)
  531. {
  532. m_dwType = DBVT_LONG;
  533. ChangeDataType(eAllocNothing);
  534. m_lVal = l;
  535. return *this;
  536. }
  537. CQueryVar& CQueryVar::operator=(long l)
  538. {
  539. m_dwType = DBVT_LONG;
  540. ChangeDataType(eAllocNothing);
  541. m_lVal = l;
  542. return *this;
  543. }
  544. CQueryVar& CQueryVar::operator=(short s)
  545. {
  546. m_dwType = DBVT_SHORT;
  547. ChangeDataType(eAllocNothing);
  548. m_iVal = s;
  549. return *this;
  550. }
  551. CQueryVar& CQueryVar::operator=(float f)
  552. {
  553. m_dwType = DBVT_SINGLE;
  554. ChangeDataType(eAllocNothing);
  555. m_fltVal = f;
  556. return *this;
  557. }
  558. CQueryVar& CQueryVar::operator=(double d)
  559. {
  560. m_dwType = DBVT_DOUBLE;
  561. ChangeDataType(eAllocNothing);
  562. m_dblVal = d;
  563. return *this;
  564. }
  565. CQueryVar& CQueryVar::operator=(COleDateTime& date)
  566. {
  567. m_dwType = DBVT_DATE;
  568. ChangeDataType(eAllocDate);
  569. m_pdate->year = date.GetYear();
  570. m_pdate->month = date.GetMonth();
  571. m_pdate->day = date.GetDay();
  572. m_pdate->hour = date.GetHour();
  573. m_pdate->minute = date.GetMinute();
  574. m_pdate->second = date.GetSecond();
  575. m_pdate->fraction = 0;
  576. return *this;
  577. }
  578. CQueryVar& CQueryVar::operator=(CLongBinary& lB)
  579. {
  580. void* pSrc;
  581. void* pDest;
  582. int allocFlags;
  583. m_dwType = DBVT_BINARY;
  584. allocFlags = m_allocFlags;
  585. ChangeDataType(eAllocBinary);
  586. if (allocFlags != eAllocBinary)
  587. m_pbinary->m_hData = GlobalAlloc(GMEM_MOVEABLE,lB.m_dwDataLength);
  588. else if (m_pbinary->m_dwDataLength != lB.m_dwDataLength)
  589. m_pbinary->m_hData = GlobalReAlloc(m_pbinary->m_hData,lB.m_dwDataLength,GMEM_MOVEABLE);
  590. pSrc  = GlobalLock(lB.m_hData);
  591. pDest = GlobalLock(m_pbinary->m_hData);
  592. memcpy(pDest,pSrc,lB.m_dwDataLength);
  593. GlobalUnlock(lB.m_hData);
  594. GlobalUnlock(m_pbinary->m_hData);
  595. m_pbinary->m_dwDataLength = lB.m_dwDataLength;
  596. return *this;
  597. }
  598. CQueryVar& CQueryVar::operator=(CQueryVar& v)
  599. {
  600. void* pSrc;
  601. void* pDest;
  602. int allocFlags;
  603. m_decPlaces = v.m_decPlaces;
  604. m_dateFormat= v.m_dateFormat;
  605. m_dwType = v.m_dwType;
  606. switch (m_dwType)
  607. {
  608. case DBVT_DATE:
  609. ChangeDataType(eAllocDate);
  610. memcpy(m_pdate,v.m_pdate,sizeof(TIMESTAMP_STRUCT));
  611. break;
  612. case DBVT_STRING:
  613. ChangeDataType(eAllocString);
  614. *m_pstring = *v.m_pstring;
  615. break;
  616. case DBVT_BINARY:
  617. allocFlags = m_allocFlags;
  618. ChangeDataType(eAllocBinary);
  619. if (allocFlags != eAllocBinary)
  620. m_pbinary->m_hData = GlobalAlloc(GMEM_MOVEABLE,v.m_pbinary->m_dwDataLength);
  621. else if (m_pbinary->m_dwDataLength != v.m_pbinary->m_dwDataLength)
  622. m_pbinary->m_hData = GlobalReAlloc(m_pbinary->m_hData,v.m_pbinary->m_dwDataLength,GMEM_MOVEABLE);
  623. pSrc  = GlobalLock(v.m_pbinary->m_hData);
  624. pDest = GlobalLock(m_pbinary->m_hData);
  625. memcpy(pDest,pSrc,v.m_pbinary->m_dwDataLength);
  626. GlobalUnlock(v.m_pbinary->m_hData);
  627. GlobalUnlock(m_pbinary->m_hData);
  628. m_pbinary->m_dwDataLength = v.m_pbinary->m_dwDataLength;
  629. break;
  630. case DBVT_NULL:
  631. ChangeDataType(eAllocNothing);
  632. break;
  633. default:
  634. ChangeDataType(eAllocNothing);
  635. m_boolVal = v.m_boolVal;
  636. m_chVal   = v.m_chVal;
  637. m_iVal    = v.m_iVal;
  638. m_lVal    = v.m_lVal;
  639. m_fltVal  = v.m_fltVal;
  640. m_dblVal  = v.m_dblVal;
  641. break;
  642. }
  643. return *this;
  644. }
  645. BOOL CQueryVar::operator==(CSQLNull& sqlNull)
  646. {
  647. return m_dwType == (DWORD)sqlNull.SqlNull;
  648. }
  649. BOOL CQueryVar::operator!=(CSQLNull& sqlNull)
  650. {
  651. return m_dwType != (DWORD)sqlNull.SqlNull;
  652. }
  653. short CQueryVar::SetDecimalDigits(short d)
  654. {
  655. short prevDecPlaces = m_decPlaces;
  656. m_decPlaces = d;
  657. return prevDecPlaces;
  658. }
  659. LPCSTR CQueryVar::SetDateFormat(LPCSTR strDateFormat)
  660. {
  661. CString oldDateFormat = m_dateFormat;
  662. m_dateFormat = strDateFormat;
  663. return oldDateFormat;
  664. }
  665. //////////////////////////////////////////////////////////////////////
  666. // V2.0 CQueryCol Class
  667. //
  668. CQueryCol::CQueryCol()
  669. {
  670. m_pValue   = NULL;
  671. m_pfldInfo = NULL;
  672. }
  673. CQueryCol::CQueryCol(CQueryVar& qv,CODBCFieldInfo& fi)
  674. {
  675. m_pValue   = &qv;
  676. m_pfldInfo = &fi;
  677. }
  678. CQueryCol::~CQueryCol()
  679. {
  680. }
  681. //////////////////////////////////////////////////////////////////////
  682. // CQueryDef Class
  683. //////////////////////////////////////////////////////////////////////
  684. IMPLEMENT_DYNAMIC(CQueryDef, CRecordset2)
  685. CQueryDef::CQueryDef(CDatabase* pDB) : CRecordset2(pDB)
  686. {
  687. m_nParams = 0;
  688. m_nFields = 0;
  689. m_nOpenType = CRecordset::forwardOnly; // helps implementation of ReOpen()
  690. m_dwOptions = CRecordset::readOnly;
  691. m_nMode = eModeNoMode;
  692. }
  693. CQueryDef::CQueryDef(CDatabase* pDB,LPCSTR strSelect) : CRecordset2(pDB)
  694. {
  695. m_nParams = 0;
  696. m_nFields = 0;
  697. m_nMode = eModeNoMode;
  698. Open(forwardOnly,strSelect,readOnly|noDirtyFieldCheck|executeDirect);
  699. }
  700. CQueryDef::~CQueryDef()
  701. {
  702. Close();
  703. }
  704. BOOL CQueryDef::Open(UINT nOpenType,LPCTSTR lpszSQL,DWORD dwOptions)
  705. {
  706. CString m_query;
  707. int i,maxQL;
  708. BOOL b;
  709. m_nOpenType = nOpenType; // helps implementation of ReOpen()
  710. m_strSQL = lpszSQL;
  711. m_dwOptions = dwOptions;
  712. m_originalQuery = lpszSQL;
  713. if (m_originalQuery.GetLength() == 0)
  714. m_originalQuery = GetDefaultSQL();
  715. for (maxQL = m_originalQuery.GetLength(), i = 0; i < maxQL; i++)
  716. {
  717. m_query += m_originalQuery[i];
  718. if (m_originalQuery[i] == '?')
  719. {
  720. m_ioParam[m_nParams] = 0;
  721. if (i+1 < maxQL && CString("LFDIYCBTX").Find(m_originalQuery[i+1]) != -1)
  722. m_ioParam[m_nParams] = m_originalQuery[++i];
  723. m_nParams++;
  724. }
  725. }
  726. m_cParam.SetSize(m_nParams);
  727. FreezeAllEvents(); // avoid NotifyMove before NotifyOpen
  728. b = CRecordset2::Open(nOpenType,m_query,dwOptions);
  729. FreezeAllEvents(FALSE); // restore notifications
  730. // V2.0 SQL column descriptors
  731. for (i = 0; i < GetODBCFieldCount(); i++)
  732. m_columns.Add(CQueryCol(m_cLine[i],m_ODBCFieldInfo[i]));
  733. NotifySink(eNotifyOpen); // is gotta be open then
  734. if (!IsEOF())
  735. NotifySink(eNotifyMove); // followed by move on the first record
  736. return b;
  737. }
  738. void CQueryDef::Close()
  739. {
  740. NotifySink(eNotifyClose);
  741. CRecordset2::Close();
  742. m_nFields = 0;
  743. m_nParams = 0;
  744. m_columns.RemoveAll();
  745. ClearEventSinkList();
  746. }
  747. BOOL CQueryDef::ReOpen(CDatabase* pDB)
  748. {
  749. if (IsOpen())
  750. Close();
  751. m_pDatabase = pDB;
  752. return Open(m_nOpenType,m_strSQL,m_dwOptions);
  753. }
  754. void CQueryDef::PreBindFields()
  755. {
  756. if (m_nFields == 0) // fetch columns information
  757. {
  758. m_nFields = GetODBCFieldCount();
  759. m_ODBCFieldInfo.SetSize(m_nFields);
  760. for (WORD i = 0; i < m_nFields; i++)
  761. GetODBCFieldInfo(i,m_ODBCFieldInfo[i]);
  762. m_cLine.SetSize(m_nFields); // make room for columns values
  763. }
  764. AllocStatusArrays(); // may change in future versions of MFC
  765. }
  766. void CQueryDef::AddNew()
  767. {
  768. m_nMode = eModeAddNew; // signal BindFields that an AddNew is in progress
  769. CRecordset2::AddNew();
  770. NotifySink(eNotifyAddNew);
  771. }
  772. void CQueryDef::Edit()
  773. {
  774. m_nMode = eModeEdit;
  775. CRecordset2::Edit();
  776. NotifySink(eNotifyEdit);
  777. }
  778. BOOL CQueryDef::Update()
  779. {
  780. BOOL bResult = CRecordset2::Update();
  781. m_nMode = eModeNoMode;
  782. NotifySink(eNotifyUpdate);
  783. return bResult;
  784. }
  785. void CQueryDef::Delete()
  786. {
  787. CRecordset2::Delete();
  788. NotifySink(eNotifyDelete);
  789. }
  790. BOOL CQueryDef::Requery()
  791. {
  792. BOOL b = CRecordset2::Requery();
  793. NotifySink(eNotifyRequery);
  794. return b;
  795. }
  796. void CQueryDef::CancelUpdate()
  797. {
  798. CRecordset2::CancelUpdate();
  799. NotifySink(eNotifyCancelUpdate);
  800. }
  801. void CQueryDef::DoFieldExchange(CFieldExchange* pFX) // input/output parameters only
  802. {
  803. BindParams(pFX);
  804. BindFields(pFX);
  805. }
  806. void CQueryDef::BindParams(CFieldExchange* pFX) // cannot have SQL_NULL outparams
  807. {
  808. USES_RecordsetPatch;
  809. unsigned int i;
  810. ASSERT(m_cParam.m_varDB.GetSize() == (WORD)m_nParams);
  811. for (i = 0; i < m_nParams; i++)
  812. {
  813. pFX->SetFieldType(m_ioParam[i]==0? CFieldExchange::inputParam : CFieldExchange::inoutParam);
  814. switch (m_ioParam[i])
  815. {
  816. case 'L':
  817. m_cParam.m_varDB[i].m_dwType = DBVT_LONG;
  818. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  819. break;
  820. case 'I':
  821. m_cParam.m_varDB[i].m_dwType = DBVT_SHORT;
  822. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  823. break;
  824. case 'Y':
  825. m_cParam.m_varDB[i].m_dwType = DBVT_UCHAR;
  826. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  827. break;
  828. case 'B':
  829. m_cParam.m_varDB[i].m_dwType = DBVT_BOOL;
  830. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  831. break;
  832. case 'C':
  833. m_cParam.m_varDB[i].m_dwType = DBVT_STRING;
  834. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocString);
  835. break;
  836. case 'F':
  837. m_cParam.m_varDB[i].m_dwType = DBVT_SINGLE;
  838. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  839. break;
  840. case 'D':
  841. m_cParam.m_varDB[i].m_dwType = DBVT_DOUBLE;
  842. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  843. break;
  844. case 'T':
  845. m_cParam.m_varDB[i].m_dwType = DBVT_DATE;
  846. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocDate);
  847. break;
  848. case 'X':
  849. m_cParam.m_varDB[i].m_dwType = DBVT_BINARY;
  850. m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocBinary);
  851. break;
  852. }
  853. switch (m_cParam.m_varDB[i].m_dwType)
  854. {
  855. case DBVT_NULL:
  856. CRecordset2::SetParamNull(i);
  857. RFX_Bool(pFX,"",m_cParam.m_varDB[i].m_boolVal); // phony binding
  858. break;
  859. case DBVT_BOOL:
  860. RFX_Bool(pFX,"",m_cParam.m_varDB[i].m_boolVal);
  861. break;
  862. case DBVT_STRING:
  863. RFX_Text(pFX,"",*m_cParam.m_varDB[i].m_pstring);
  864. break;
  865. case DBVT_UCHAR:
  866. RFX_Byte(pFX,"",m_cParam.m_varDB[i].m_chVal);
  867. break;
  868. case DBVT_LONG:
  869. RFX_Long(pFX,"",m_cParam.m_varDB[i].m_lVal);
  870. break;
  871. case DBVT_SHORT:
  872. RFX_Int(pFX,"",(int&)m_cParam.m_varDB[i].m_iVal);
  873. break;
  874. case DBVT_SINGLE:
  875. RFX_Single(pFX,"",m_cParam.m_varDB[i].m_fltVal);
  876. break;
  877. case DBVT_DOUBLE:
  878. RFX_Double(pFX,"",m_cParam.m_varDB[i].m_dblVal);
  879. break;
  880. case DBVT_DATE:
  881. RFX_Date(pFX,"",*m_cParam.m_varDB[i].m_pdate);
  882. break;
  883. case DBVT_BINARY:
  884. RFX_LongBinary(pFX,"",*m_cParam.m_varDB[i].m_pbinary);
  885. break;
  886. }
  887. }
  888. }
  889. void CQueryDef::BindFields(CFieldExchange* pFX)
  890. {
  891. static BOOL bReentrant = FALSE;
  892. DWORD dwType;
  893. USES_RecordsetPatch;
  894. for (UINT i = 0; i < m_nFields; i++)
  895. {
  896. if (!bReentrant && m_nMode != eModeNoMode) // AddNew or Edit
  897. {
  898. bReentrant = TRUE;
  899. if (m_cLine.m_varDB[i].m_dwType == DBVT_NULL)
  900. CRecordset::SetFieldNull(m_cLine.m_varDB[i],TRUE);
  901. else
  902. CRecordset::SetFieldNull(m_cLine.m_varDB[i],FALSE);
  903. bReentrant = FALSE;
  904. }
  905. pFX->SetFieldType(CFieldExchange::outputColumn);
  906. switch (m_ODBCFieldInfo[i].m_nSQLType)
  907. {
  908. case SQL_DATE:
  909. case SQL_TIME:
  910. case SQL_TIMESTAMP:
  911. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocDate);
  912. RFX_Date(pFX,m_ODBCFieldInfo[i].m_strName,*m_cLine.m_varDB[i].m_pdate);
  913. dwType = DBVT_DATE;
  914. break;
  915. case SQL_NUMERIC:
  916. case SQL_DECIMAL:
  917. case SQL_BIGINT:
  918. case SQL_CHAR:
  919. case SQL_VARCHAR:
  920. case SQL_LONGVARCHAR:
  921. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocString);
  922. RFX_Text(pFX,m_ODBCFieldInfo[i].m_strName,*m_cLine.m_varDB[i].m_pstring);
  923. dwType = DBVT_STRING;
  924. break;
  925. case SQL_BINARY:
  926. case SQL_VARBINARY:
  927. case SQL_LONGVARBINARY:
  928. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocBinary);
  929. RFX_LongBinary(pFX,m_ODBCFieldInfo[i].m_strName,*m_cLine.m_varDB[i].m_pbinary);
  930. dwType = DBVT_BINARY;
  931. break;
  932. case SQL_BIT:
  933. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  934. RFX_Bool(pFX,m_ODBCFieldInfo[i].m_strName,m_cLine.m_varDB[i].m_boolVal);
  935. dwType = DBVT_BOOL;
  936. break;
  937. case SQL_TINYINT:
  938. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  939. RFX_Byte(pFX,m_ODBCFieldInfo[i].m_strName,(BYTE&)m_cLine.m_varDB[i].m_iVal);
  940. dwType = DBVT_SHORT;
  941. break;
  942. case SQL_SMALLINT:
  943. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  944. RFX_Int(pFX,m_ODBCFieldInfo[i].m_strName,(int&)m_cLine.m_varDB[i].m_iVal);
  945. dwType = DBVT_SHORT;
  946. break;
  947. case SQL_INTEGER:
  948. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  949. RFX_Long(pFX,m_ODBCFieldInfo[i].m_strName,m_cLine.m_varDB[i].m_lVal);
  950. dwType = DBVT_LONG;
  951. break;
  952. case SQL_REAL:
  953. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  954. RFX_Single(pFX,m_ODBCFieldInfo[i].m_strName,m_cLine.m_varDB[i].m_fltVal);
  955. dwType = DBVT_SINGLE;
  956. break;
  957. case SQL_FLOAT:
  958. case SQL_DOUBLE:
  959. m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  960. RFX_Double(pFX,m_ODBCFieldInfo[i].m_strName,m_cLine.m_varDB[i].m_dblVal);
  961. dwType = DBVT_DOUBLE;
  962. break;
  963. }
  964. if (m_nMode == eModeNoMode)
  965. {
  966. m_cLine.m_varDB[i].m_dwType = dwType;
  967. if (IsFieldStatusNull(i))
  968. {
  969. // m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
  970. m_cLine.m_varDB[i].m_dwType = DBVT_NULL;
  971. }
  972. }
  973. }
  974. }
  975. /* removed from V1.5 & later; has been replaced with RFX_xxx binding functions
  976. void CQueryDef::GetSQLData()
  977. {
  978. for (short i = 0; i < GetODBCFieldCount(); i++)
  979. {
  980. m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocNothing;
  981. GetFieldValue(i,m_cLine.m_varDB[i]);
  982. switch (m_ODBCFieldInfo[i].m_nSQLType)
  983. {
  984. case SQL_DATE:
  985. case SQL_TIME:
  986. case SQL_TIMESTAMP:
  987. m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocDate;
  988. break;
  989. case SQL_NUMERIC:
  990. case SQL_DECIMAL:
  991. case SQL_BIGINT:
  992. case SQL_CHAR:
  993. case SQL_VARCHAR:
  994. case SQL_LONGVARCHAR:
  995. m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocString;
  996. break;
  997. case SQL_BINARY:
  998. case SQL_VARBINARY:
  999. case SQL_LONGVARBINARY:
  1000. m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocBinary;
  1001. break;
  1002. default:
  1003. m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocNothing;
  1004. break;
  1005. }
  1006. }
  1007. }
  1008. */
  1009. CQueryVar& CQueryDef::operator[](int index)
  1010. {
  1011. return m_cLine[index];
  1012. }
  1013. CQueryVar& CQueryDef::operator[](LPCTSTR lpszColumnName) // applies only on columns
  1014. {
  1015. for (int i = 0; i < GetODBCFieldCount(); i++)
  1016. if (m_ODBCFieldInfo[i].m_strName == lpszColumnName)
  1017. return m_cLine[i];
  1018. throw CQueryVar::eBoundary;
  1019. return CQueryVar(); // never called
  1020. }
  1021. CQueryVariant& CQueryDef::operator=(CQueryVariant& v)
  1022. {
  1023. v.m_decPlaces = m_cLine.m_decPlaces;
  1024. v.m_dateFormat = m_cLine.m_dateFormat;
  1025. v.SetSize(m_cLine.Columns());
  1026. for (WORD i = 0; i < v.Columns(); i++)
  1027. v.m_varDB[i] = m_cLine.m_varDB[i];
  1028. return v;
  1029. }
  1030. void CQueryDef::Move(long nRows,WORD wFetchType)
  1031. {
  1032. try
  1033. {
  1034. CRecordset::Move(nRows,wFetchType);
  1035. }
  1036. catch (CDBException* e) // no rowset; parameters only
  1037. {
  1038. if (e->m_strStateNativeOrigin.Left(11) != "State:24000") // invalid cursor state
  1039. throw e;
  1040. e->Delete();
  1041. if (m_bEOF) // already been here
  1042. return;
  1043. m_bEOF = m_bBOF = TRUE;
  1044. ASSERT_VALID(this);
  1045. ASSERT(m_hstmt != SQL_NULL_HSTMT);
  1046. CFieldExchange fx(CFieldExchange::Fixup,this); // fixup strings
  1047. fx.m_hstmt = m_hstmt;
  1048. DoFieldExchange(&fx);
  1049. }
  1050. NotifySink(eNotifyMove);
  1051. // if (!IsEOF())
  1052. // GetSQLData();
  1053. }
  1054. short CQueryDef::SetDecimalDigits(short d)
  1055. {
  1056. short s = m_cLine.SetDecimalDigits(d);
  1057. NotifySink(eNotifyFormatChanged,eFormatChangedDecimalDigits);
  1058. return s;
  1059. }
  1060. LPCSTR CQueryDef::SetDateFormat(LPCSTR strFormat)
  1061. {
  1062. LPCSTR lpstr = m_cLine.SetDateFormat(strFormat);
  1063. NotifySink(eNotifyFormatChanged,eFormatChangedDate);
  1064. return lpstr;
  1065. }
  1066. CQueryCol& CQueryDef::Column(LPCTSTR lpColName)
  1067. {
  1068. for (int i = 0; i < m_columns.GetSize(); i++)
  1069. if (strcmp(m_columns[i].Name(),lpColName) == 0)
  1070. return m_columns[i];
  1071. throw CQueryVar::eBoundary;
  1072. return CQueryCol(CQueryVar(),CODBCFieldInfo());
  1073. }
  1074. EVNHANDLE CQueryDef::Advise(IQueryDefEventSink* pSink)
  1075. {
  1076. return m_evSink.AddTail(new SQueryDefEventSink(pSink,FALSE));
  1077. }
  1078. void CQueryDef::Unadvise(EVNHANDLE evnHandle)
  1079. {
  1080. m_evSink.RemoveAt(evnHandle);
  1081. }
  1082. void CQueryDef::FreezeEvents(EVNHANDLE evnHandle,BOOL bFreeze)
  1083. {
  1084. m_evSink.GetAt(evnHandle)->m_frozen = bFreeze;
  1085. }
  1086. void CQueryDef::FreezeAllEvents(BOOL bFreeze)
  1087. {
  1088. // freeze all events keeping track of already frozen ones
  1089. EVNHANDLE posHandle = m_evSink.GetHeadPosition();
  1090. SQueryDefEventSink* pSink;
  1091. int inc = bFreeze? +1 : -1;
  1092. while (posHandle)
  1093. {
  1094. pSink = m_evSink.GetNext(posHandle);
  1095. pSink->m_frozen += inc; // if 0 -> 1 if 1 -> 2 (all frozen)
  1096. }
  1097. }
  1098. void CQueryDef::ClearEventSinkList()
  1099. {
  1100. EVNHANDLE evH = m_evSink.GetHeadPosition();
  1101. while (evH != NULL)
  1102. delete m_evSink.GetNext(evH);
  1103. m_evSink.RemoveAll();
  1104. }
  1105. void CQueryDef::NotifySink(ENOTIFICATION nNotify,LPARAM lp)
  1106. {
  1107. SQueryDefEventSink* pSink;
  1108. EVNHANDLE evnH = m_evSink.GetHeadPosition();
  1109. EVNHANDLE evnHPrev;
  1110. LPARAM retVal;
  1111. while (evnH != NULL)
  1112. {
  1113. evnHPrev = evnH;
  1114. pSink = m_evSink.GetNext(evnH);
  1115. if (pSink->m_frozen)
  1116. continue;
  1117. // a sink returning non 0 value blocks all the other sinks receiving the notification
  1118. switch (nNotify)
  1119. {
  1120. case eNotifyOpen:
  1121. retVal = pSink->m_pSink->RSNotifyOpen(evnHPrev);
  1122. break;
  1123. case eNotifyClose:
  1124. retVal = pSink->m_pSink->RSNotifyClose(evnHPrev);
  1125. break;
  1126. case eNotifyMove:
  1127. retVal = pSink->m_pSink->RSNotifyMove(evnHPrev);
  1128. break;
  1129. case eNotifyAddNew:
  1130. retVal = pSink->m_pSink->RSNotifyAddNew(evnHPrev);
  1131. break;
  1132. case eNotifyEdit:
  1133. retVal = pSink->m_pSink->RSNotifyEdit(evnHPrev);
  1134. break;
  1135. case eNotifyUpdate:
  1136. retVal = pSink->m_pSink->RSNotifyUpdate(evnHPrev);
  1137. break;
  1138. case eNotifyDelete:
  1139. retVal = pSink->m_pSink->RSNotifyDelete(evnHPrev);
  1140. break;
  1141. case eNotifyCancelUpdate:
  1142. retVal = pSink->m_pSink->RSNotifyCancelUpdate(evnHPrev);
  1143. break;
  1144. case eNotifyRequery:
  1145. retVal = pSink->m_pSink->RSNotifyRequery(evnHPrev);
  1146. break;
  1147. case eNotifyFormatChanged:
  1148. retVal = pSink->m_pSink->RSNotifyFormatChanged(evnHPrev,(BYTE)lp);
  1149. break;
  1150. default:
  1151. break;
  1152. }
  1153. if (retVal != 0) // blocks event bubbling
  1154. return;
  1155. }
  1156. }
  1157. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1158. // class CTabbedString
  1159. //
  1160. CTabbedString& CTabbedString::operator=(CQueryDef& qDef)
  1161. {
  1162. WORD nCount = qDef.GetODBCFieldCount();
  1163. CQueryVar varTemp;
  1164. Empty();
  1165. for (WORD i = 0; i < nCount; i++)
  1166. {
  1167. varTemp = (CQueryVar&)qDef.m_cLine.m_varDB[i];
  1168. if (!varTemp.IsNull())
  1169. *this += (LPCTSTR)varTemp;
  1170. else
  1171. *this += "<NULL>";
  1172. if (i+1 < nCount)
  1173. *this += 't';
  1174. }
  1175. return *this;
  1176. }
  1177. CTabbedString& CTabbedString::operator=(CQueryVariant& qV)
  1178. {
  1179. WORD nCount = qV.Columns();
  1180. CQueryVar varTemp;
  1181. Empty();
  1182. for (WORD i = 0; i < nCount; i++)
  1183. {
  1184. varTemp = (CQueryVar&)qV.m_varDB[i];
  1185. if (!varTemp.IsNull())
  1186. *this += (LPCTSTR)varTemp;
  1187. else
  1188. *this += "<NULL>";
  1189. if (i+1 < nCount)
  1190. *this += 't';
  1191. }
  1192. return *this;
  1193. }
  1194. CTabbedString CTabbedString::operator[](int index)
  1195. {
  1196. CString strRet;
  1197. int nLength = GetLength();
  1198. for (int i = 0; i < nLength; i++)
  1199. {
  1200. if (GetAt(i) == 't' && --index == 0)
  1201. {
  1202. i++;
  1203. while (i < nLength && GetAt(i) != 't')
  1204. strRet += GetAt(i++);
  1205. }
  1206. }
  1207. if (index > -1)
  1208. throw CQueryVariant::eBoundary;
  1209. return strRet;
  1210. }
  1211. BOOL CTabbedString::IsNull(int index)
  1212. {
  1213. return operator[](index) == "<NULL>";
  1214. }
  1215. BOOL CTabbedString::operator==(CSQLNull&)
  1216. {
  1217. return *this == "<NULL>";
  1218. }
  1219. BOOL CTabbedString::operator!=(CSQLNull&)
  1220. {
  1221. return *this != "<NULL>";
  1222. }
  1223. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1224. // class CSQLNull
  1225. //
  1226. const int CSQLNull::SqlNull = DBVT_NULL; // taken from CDBVariant;
  1227. BOOL CSQLNull::operator==(CQueryVar& qVar)
  1228. {
  1229. return SqlNull == qVar.m_dwType;
  1230. }
  1231. BOOL CSQLNull::operator!=(CQueryVar& qVar)
  1232. {
  1233. return SqlNull != qVar.m_dwType;
  1234. }
  1235. BOOL CSQLNull::operator==(CTabbedString& strTab)
  1236. {
  1237. return strTab == "<NULL>";
  1238. }
  1239. BOOL CSQLNull::operator!=(CTabbedString& strTab)
  1240. {
  1241. return strTab != "<NULL>";
  1242. }
  1243. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1244. CString ConvertToHex(void* pbinary,int length) // converts a binary stream to hex representation
  1245. {
  1246. int i;
  1247. char* p;
  1248. CString s;
  1249. BYTE b;
  1250. for (i = 0, p = static_cast<char*>(pbinary); i < length; i++, p++)
  1251. {
  1252. b = *p & 0xF0;
  1253. s += chHexDigits[b>>4];
  1254. b = *p & 0x0F;
  1255. s += chHexDigits[b];
  1256. }
  1257. s = (CString)"0x" + s;
  1258. return s;
  1259. }
  1260. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1261. }; // namespace QueryDef
  1262. #if defined(_QUERYDEFCOMPILE)
  1263. __declspec(dllexport) QueryDef::CSQLNull SQL_NULL; // value of SQL NULL as defined by this class
  1264. #endif