daodfx.cpp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #include "math.h"
  12. #ifdef AFX_DB_SEG
  13. #pragma code_seg(AFX_DB_SEG)
  14. #endif
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. #define new DEBUG_NEW
  20. //////////////////////////////////////////////////////////////////////////
  21. // Helpers
  22. // Helpers for floating point operations
  23. AFX_STATIC_DATA const float _afxFloatPseudoNull = AFX_RFX_SINGLE_PSEUDO_NULL;
  24. AFX_STATIC_DATA const double _afxDoublePseudoNull = AFX_RFX_DOUBLE_PSEUDO_NULL;
  25. // Long binary allocation helper
  26. void AFX_CDECL AllocLongBinary(CLongBinary& lb, DWORD dwDataLength);
  27. // Memory allocation callbacks used by ICDAOGetRows
  28. STDAPI DaoStringAllocCallback(DWORD dwLen, DWORD pData, void** ppv);
  29. STDAPI DaoBinaryAllocCallback(DWORD dwLen, DWORD pData, void** ppv);
  30. STDAPI DaoLongBinaryAllocCallback(DWORD dwLen, DWORD pData, void** ppv);
  31. //////////////////////////////////////////////////////////////////////////
  32. // CDaoFieldExchange
  33. CDaoFieldExchange::CDaoFieldExchange(UINT nOperation,
  34. CDaoRecordset* prs, void* pvField)
  35. {
  36. ASSERT(nOperation < MaxDFXOperation);
  37. m_nFieldType = none;
  38. m_nOperation = nOperation;
  39. m_prs = prs;
  40. m_pvField = pvField;
  41. m_nField = 0;
  42. m_nParam = 0;
  43. }
  44. BOOL CDaoFieldExchange::IsValidOperation()
  45. {
  46. if (m_nOperation >= MaxDFXOperation)
  47. {
  48. // Invalid operation
  49. ASSERT(FALSE);
  50. return FALSE;
  51. }
  52. // Operations valid for both field types
  53. #ifdef _DEBUG
  54. if (m_nOperation == DumpField || m_nOperation == SetFieldNull)
  55. return TRUE;
  56. #endif
  57. // Operations only valid for outputColumn OR param types
  58. if ((m_nOperation == AddToParameterList) ||
  59. (m_nOperation == BindParam))
  60. return (m_nFieldType == param);
  61. else
  62. return (m_nFieldType == outputColumn);
  63. }
  64. void CDaoFieldExchange::AppendParamType(CString& strParamList,
  65. DWORD dwParamType)
  66. {
  67. switch (dwParamType)
  68. {
  69. default:
  70. ASSERT(FALSE);
  71. break;
  72. case AFX_RFX_TEXT:
  73. strParamList += " Text";
  74. break;
  75. case AFX_RFX_BINARY:
  76. strParamList += " LongBinary";
  77. break;
  78. case AFX_RFX_LONGBINARY:
  79. strParamList += " LongBinary";
  80. break;
  81. case AFX_RFX_BOOL:
  82. strParamList += " Bit";
  83. break;
  84. case AFX_RFX_BYTE:
  85. strParamList += " Byte";
  86. break;
  87. case AFX_RFX_SHORT:
  88. strParamList += " Short";
  89. break;
  90. case AFX_RFX_LONG:
  91. strParamList += " Long";
  92. break;
  93. case AFX_RFX_CURRENCY:
  94. strParamList += " Currency";
  95. break;
  96. case AFX_RFX_SINGLE:
  97. strParamList += " IEEESingle";
  98. break;
  99. case AFX_RFX_DOUBLE:
  100. strParamList += " IEEEDouble";
  101. break;
  102. case AFX_RFX_DATE:
  103. strParamList += " DateTime";
  104. break;
  105. }
  106. }
  107. CDaoFieldCache* CDaoFieldExchange::GetCacheValue(CDaoRecordset* prs, void* pv)
  108. {
  109. // Lookup storage locations
  110. void* pvCache;
  111. if (!prs->m_pMapFieldCache->Lookup(pv, pvCache))
  112. AfxThrowDaoException(AFX_DAO_ERROR_DFX_BIND);
  113. return (CDaoFieldCache*)pvCache;
  114. }
  115. void CDaoFieldExchange::SetNullValue(void* pv, DWORD dwDataType)
  116. {
  117. switch (dwDataType)
  118. {
  119. default:
  120. ASSERT(FALSE);
  121. break;
  122. case AFX_RFX_TEXT:
  123. ((CString*)pv)->Empty();
  124. break;
  125. case AFX_RFX_BINARY:
  126. ((CByteArray*)pv)->SetSize(0);
  127. break;
  128. case AFX_RFX_LONGBINARY:
  129. ((CLongBinary*)pv)->m_dwDataLength = 0;
  130. break;
  131. case AFX_RFX_BOOL:
  132. *(BOOL*)pv = AFX_RFX_BOOL_PSEUDO_NULL;
  133. break;
  134. case AFX_RFX_BYTE:
  135. *(BYTE*)pv = AFX_RFX_BYTE_PSEUDO_NULL;
  136. break;
  137. case AFX_RFX_SHORT:
  138. *(short*)pv = AFX_RFX_SHORT_PSEUDO_NULL;
  139. break;
  140. case AFX_RFX_LONG:
  141. *(long*)pv = AFX_RFX_LONG_PSEUDO_NULL;
  142. break;
  143. case AFX_RFX_CURRENCY:
  144. ((COleCurrency*)pv)->SetStatus(COleCurrency::null);
  145. break;
  146. case AFX_RFX_SINGLE:
  147. *(float*)pv = _afxFloatPseudoNull;
  148. break;
  149. case AFX_RFX_DOUBLE:
  150. *(double*)pv = _afxDoublePseudoNull;
  151. break;
  152. case AFX_RFX_DATE:
  153. ((COleDateTime*)pv)->SetStatus(COleDateTime::null);
  154. break;
  155. }
  156. }
  157. BOOL CDaoFieldExchange::IsNullValue(void* pv, DWORD dwDataType)
  158. {
  159. BOOL bNull = FALSE;
  160. switch (dwDataType)
  161. {
  162. default:
  163. ASSERT(FALSE);
  164. break;
  165. case AFX_RFX_TEXT:
  166. if (((CString*)pv)->IsEmpty())
  167. bNull = TRUE;
  168. break;
  169. case AFX_RFX_BINARY:
  170. if (((CByteArray*)pv)->GetSize() == 0)
  171. bNull = TRUE;
  172. break;
  173. case AFX_RFX_LONGBINARY:
  174. if (((CLongBinary*)pv)->m_dwDataLength == 0)
  175. bNull = TRUE;
  176. break;
  177. case AFX_RFX_BOOL:
  178. if (*(BOOL*)pv == AFX_RFX_BOOL_PSEUDO_NULL)
  179. bNull = TRUE;
  180. break;
  181. case AFX_RFX_BYTE:
  182. if (*(BYTE*)pv == AFX_RFX_BYTE_PSEUDO_NULL)
  183. bNull = TRUE;
  184. break;
  185. case AFX_RFX_SHORT:
  186. if (*(short*)pv == AFX_RFX_SHORT_PSEUDO_NULL)
  187. bNull = TRUE;
  188. break;
  189. case AFX_RFX_LONG:
  190. if (*(long*)pv == AFX_RFX_LONG_PSEUDO_NULL)
  191. bNull = TRUE;
  192. break;
  193. case AFX_RFX_CURRENCY:
  194. if (((COleCurrency*)pv)->GetStatus() == COleCurrency::null)
  195. bNull = TRUE;
  196. break;
  197. case AFX_RFX_SINGLE:
  198. if (*(float*)pv == _afxFloatPseudoNull)
  199. bNull = TRUE;
  200. break;
  201. case AFX_RFX_DOUBLE:
  202. if (*(double*)pv == _afxDoublePseudoNull)
  203. bNull = TRUE;
  204. break;
  205. case AFX_RFX_DATE:
  206. if (((COleDateTime*)pv)->GetStatus() == COleDateTime::null)
  207. bNull = TRUE;
  208. break;
  209. }
  210. return bNull;
  211. }
  212. void CDaoFieldExchange::AllocCacheValue(CDaoFieldCache*& pCache,
  213. DWORD dwDataType)
  214. {
  215. // Initialize a new field cache
  216. pCache = new CDaoFieldCache;
  217. pCache->m_nStatus = 0;
  218. switch (dwDataType)
  219. {
  220. default:
  221. ASSERT(FALSE);
  222. break;
  223. case AFX_RFX_TEXT:
  224. pCache->m_pvData = new CString();
  225. pCache->m_nDataType = AFX_RFX_TEXT;
  226. break;
  227. case AFX_RFX_BINARY:
  228. pCache->m_pvData = new CByteArray();
  229. pCache->m_nDataType = AFX_RFX_BINARY;
  230. break;
  231. case AFX_RFX_LONGBINARY:
  232. pCache->m_pvData = new CLongBinary();
  233. pCache->m_nDataType = AFX_RFX_LONGBINARY;
  234. break;
  235. case AFX_RFX_BOOL:
  236. pCache->m_nDataType = AFX_RFX_BOOL;
  237. break;
  238. case AFX_RFX_BYTE:
  239. pCache->m_nDataType = AFX_RFX_BYTE;
  240. break;
  241. case AFX_RFX_SHORT:
  242. pCache->m_nDataType = AFX_RFX_SHORT;
  243. break;
  244. case AFX_RFX_LONG:
  245. pCache->m_nDataType = AFX_RFX_LONG;
  246. break;
  247. case AFX_RFX_CURRENCY:
  248. pCache->m_pvData = new COleCurrency();
  249. pCache->m_nDataType = AFX_RFX_CURRENCY;
  250. break;
  251. case AFX_RFX_SINGLE:
  252. pCache->m_nDataType = AFX_RFX_SINGLE;
  253. break;
  254. case AFX_RFX_DOUBLE:
  255. pCache->m_pvData = new double;
  256. pCache->m_nDataType = AFX_RFX_DOUBLE;
  257. break;
  258. case AFX_RFX_DATE:
  259. pCache->m_pvData = new COleDateTime();
  260. pCache->m_nDataType = AFX_RFX_DATE;
  261. break;
  262. }
  263. }
  264. void CDaoFieldExchange::DeleteCacheValue(CDaoFieldCache* pCache,
  265. DWORD dwDataType)
  266. {
  267. switch (dwDataType)
  268. {
  269. default:
  270. ASSERT(FALSE);
  271. break;
  272. case AFX_RFX_TEXT:
  273. delete (CString*)pCache->m_pvData;
  274. break;
  275. case AFX_RFX_BINARY:
  276. delete (CByteArray*)pCache->m_pvData;
  277. break;
  278. case AFX_RFX_LONGBINARY:
  279. delete (CLongBinary*)pCache->m_pvData;
  280. break;
  281. case AFX_RFX_BOOL:
  282. case AFX_RFX_BYTE:
  283. case AFX_RFX_SHORT:
  284. case AFX_RFX_LONG:
  285. case AFX_RFX_SINGLE:
  286. break;
  287. case AFX_RFX_CURRENCY:
  288. delete (COleCurrency*)pCache->m_pvData;
  289. break;
  290. case AFX_RFX_DOUBLE:
  291. delete (double*)pCache->m_pvData;
  292. break;
  293. case AFX_RFX_DATE:
  294. delete (COleDateTime*)pCache->m_pvData;
  295. break;
  296. }
  297. delete pCache;
  298. pCache = NULL;
  299. }
  300. void CDaoFieldExchange::CopyValue(void* pvSrc, void* pvDest,
  301. DWORD dwDataType)
  302. {
  303. switch (dwDataType)
  304. {
  305. default:
  306. ASSERT(FALSE);
  307. break;
  308. case AFX_RFX_TEXT:
  309. *(CString*)pvDest = *(CString*)pvSrc;
  310. break;
  311. case AFX_RFX_BINARY:
  312. ((CByteArray*)pvDest)->Copy(*(CByteArray*)pvSrc);
  313. break;
  314. case AFX_RFX_LONGBINARY:
  315. {
  316. CLongBinary* pLongBinarySrc = (CLongBinary*)pvSrc;
  317. CLongBinary* pLongBinaryDest = (CLongBinary*)pvDest;
  318. // Reallocate memory in destination if necessary
  319. AllocLongBinary(*pLongBinaryDest, pLongBinarySrc->m_dwDataLength);
  320. pLongBinaryDest->m_dwDataLength =
  321. pLongBinarySrc->m_dwDataLength;
  322. BYTE* pbSrc = (BYTE*)::GlobalLock(pLongBinarySrc->m_hData);
  323. BYTE* pbDest = (BYTE*)::GlobalLock(pLongBinaryDest->m_hData);
  324. memcpy(pbDest, pbSrc, pLongBinarySrc->m_dwDataLength);
  325. ::GlobalUnlock(pLongBinarySrc->m_hData);
  326. ::GlobalUnlock(pLongBinaryDest->m_hData);
  327. }
  328. break;
  329. case AFX_RFX_BOOL:
  330. *(BOOL*)pvDest = *(BOOL*)pvSrc;
  331. break;
  332. case AFX_RFX_BYTE:
  333. *(BYTE*)pvDest = *(BYTE*)pvSrc;
  334. break;
  335. case AFX_RFX_SHORT:
  336. *(short*)pvDest = *(short*)pvSrc;
  337. break;
  338. case AFX_RFX_LONG:
  339. *(long*)pvDest = *(long*)pvSrc;
  340. break;
  341. case AFX_RFX_CURRENCY:
  342. *(COleCurrency*)pvDest = *(COleCurrency*)pvSrc;
  343. break;
  344. case AFX_RFX_SINGLE:
  345. *(float*)pvDest = *(float*)pvSrc;
  346. break;
  347. case AFX_RFX_DOUBLE:
  348. *(double*)pvDest = *(double*)pvSrc;
  349. break;
  350. case AFX_RFX_DATE:
  351. *(COleDateTime*)pvDest = *(COleDateTime*)pvSrc;
  352. break;
  353. }
  354. }
  355. BOOL CDaoFieldExchange::CompareValue(void* pvSrc, void* pvDest,
  356. DWORD dwDataType)
  357. {
  358. BOOL bDirty = FALSE;
  359. switch (dwDataType)
  360. {
  361. default:
  362. ASSERT(FALSE);
  363. break;
  364. case AFX_RFX_TEXT:
  365. if (*(CString*)pvDest != *(CString*)pvSrc)
  366. bDirty = TRUE;
  367. break;
  368. case AFX_RFX_BINARY:
  369. {
  370. CByteArray* pByteArraySrc = (CByteArray*)pvSrc;
  371. CByteArray* pByteArrayDest = (CByteArray*)pvDest;
  372. int nSize = pByteArraySrc->GetSize();
  373. // If sizes don't compare, must be dirty
  374. if (nSize != pByteArrayDest->GetSize())
  375. bDirty = TRUE;
  376. else
  377. {
  378. // If sizes compare, compare the data
  379. if (memcmp(&pByteArrayDest[0], &pByteArraySrc[0], nSize) != 0)
  380. bDirty = TRUE;
  381. }
  382. }
  383. break;
  384. case AFX_RFX_LONGBINARY:
  385. {
  386. CLongBinary* pLongBinarySrc = (CLongBinary*)pvSrc;
  387. CLongBinary* pLongBinaryDest = (CLongBinary*)pvDest;
  388. BYTE* pbSrc = (BYTE*)::GlobalLock(pLongBinarySrc->m_hData);
  389. BYTE* pbDest = (BYTE*)::GlobalLock(pLongBinaryDest->m_hData);
  390. // If sizes don't compare, must be dirty
  391. if (pLongBinarySrc->m_dwDataLength !=
  392. pLongBinaryDest->m_dwDataLength)
  393. {
  394. bDirty = TRUE;
  395. }
  396. else
  397. {
  398. // If sizes compare, compare the data
  399. if (memcmp(pbDest, pbSrc, pLongBinarySrc->m_dwDataLength) != 0)
  400. bDirty = TRUE;
  401. }
  402. ::GlobalUnlock(pLongBinarySrc->m_hData);
  403. ::GlobalUnlock(pLongBinaryDest->m_hData);
  404. }
  405. break;
  406. case AFX_RFX_BOOL:
  407. if (*(BOOL*)pvDest != *(BOOL*)pvSrc)
  408. bDirty = TRUE;
  409. break;
  410. case AFX_RFX_BYTE:
  411. if (*(BYTE*)pvDest != *(BYTE*)pvSrc)
  412. bDirty = TRUE;
  413. break;
  414. case AFX_RFX_SHORT:
  415. if (*(short*)pvDest != *(short*)pvSrc)
  416. bDirty = TRUE;
  417. break;
  418. case AFX_RFX_LONG:
  419. if (*(long*)pvDest != *(long*)pvSrc)
  420. bDirty = TRUE;
  421. break;
  422. case AFX_RFX_CURRENCY:
  423. if (*(COleCurrency*)pvDest != *(COleCurrency*)pvSrc)
  424. bDirty = TRUE;
  425. break;
  426. case AFX_RFX_SINGLE:
  427. if (*(float*)pvDest != *(float*)pvSrc)
  428. bDirty = TRUE;
  429. break;
  430. case AFX_RFX_DOUBLE:
  431. if (*(double*)pvDest != *(double*)pvSrc)
  432. bDirty = TRUE;
  433. break;
  434. case AFX_RFX_DATE:
  435. if (*(COleDateTime*)pvDest != *(COleDateTime*)pvSrc)
  436. bDirty = TRUE;
  437. break;
  438. }
  439. return bDirty;
  440. }
  441. void CDaoFieldExchange::FillVariant(void* pvValue, DWORD dwDataType,
  442. COleVariant** ppVar)
  443. {
  444. COleVariant* pVar;
  445. if (dwDataType == AFX_RFX_TEXT)
  446. pVar = new COleVariant(*(CString*)pvValue, VT_BSTRT);
  447. else if (dwDataType == AFX_RFX_BOOL)
  448. pVar = new COleVariant(*(long*)pvValue, VT_BOOL);
  449. else
  450. {
  451. pVar = new COleVariant;
  452. switch (dwDataType)
  453. {
  454. default:
  455. ASSERT(FALSE);
  456. break;
  457. case AFX_RFX_BINARY:
  458. *pVar = *(CByteArray*)pvValue;
  459. break;
  460. case AFX_RFX_LONGBINARY:
  461. *pVar = *(CLongBinary*)pvValue;
  462. break;
  463. case AFX_RFX_BYTE:
  464. *pVar = *(BYTE*)pvValue;
  465. break;
  466. case AFX_RFX_SHORT:
  467. *pVar = *(short*)pvValue;
  468. break;
  469. case AFX_RFX_LONG:
  470. *pVar = *(long*)pvValue;
  471. break;
  472. case AFX_RFX_CURRENCY:
  473. *pVar = *(COleCurrency*)pvValue;
  474. break;
  475. case AFX_RFX_SINGLE:
  476. *pVar = *(float*)pvValue;
  477. break;
  478. case AFX_RFX_DOUBLE:
  479. *pVar = *(double*)pvValue;
  480. break;
  481. case AFX_RFX_DATE:
  482. *pVar = *(COleDateTime*)pvValue;
  483. }
  484. }
  485. *ppVar = pVar;
  486. }
  487. // Default implementation for RFX functions
  488. void CDaoFieldExchange::Default(LPCTSTR lpszName, void* pv,
  489. DWORD dwColumnType, DWORD dwBindOptions)
  490. {
  491. switch (m_nOperation)
  492. {
  493. case AddToParameterList:
  494. if (m_nParam != 1)
  495. m_prs->m_strSQL += ",";
  496. m_prs->m_strSQL += lpszName;
  497. AppendParamType(m_prs->m_strSQL, dwColumnType);
  498. return;
  499. case AddToSelectList:
  500. if (m_nField != 1)
  501. m_prs->m_strSQL += ",";
  502. m_prs->m_strSQL += lpszName;
  503. return;
  504. case BindField:
  505. {
  506. // Query parser needs "[" & "]", GetRows can't tolerate them.
  507. LPTSTR lpszNoBracketName = new TCHAR[lstrlen(lpszName) + 1];
  508. m_prs->StripBrackets(lpszName, lpszNoBracketName);
  509. // Finish setting up column binding info struct
  510. LPDAOCOLUMNBINDING pcb =
  511. &m_prs->m_prgDaoColBindInfo[m_nField-1];
  512. pcb->cbInfoOffset =
  513. (DWORD)&m_prs->m_pulColumnLengths[m_nField-1];
  514. #ifndef _UNICODE
  515. pcb->columnID.dwKind = DAOCOLKIND_STR;
  516. pcb->columnID.lpstr = lpszNoBracketName;
  517. #else
  518. pcb->columnID.dwKind = DAOCOLKIND_WSTR;
  519. pcb->columnID.lpwstr = lpszNoBracketName;
  520. #endif
  521. // Setup the field index map (and store value as void ptr)
  522. m_prs->m_pMapFieldIndex->SetAt(pv, (void*)m_nField);
  523. }
  524. return;
  525. case BindParam:
  526. {
  527. COleVariant* pvar = NULL;
  528. TRY
  529. {
  530. // NULL params not supported, use IS NULL in SQL
  531. // (i.e. - m_strFilter = _T("Foo IS NULL");
  532. FillVariant(pv, dwColumnType, &pvar);
  533. m_prs->m_pQueryDef->SetParamValue(lpszName, *pvar);
  534. }
  535. CATCH_ALL(e)
  536. {
  537. if (pvar != NULL)
  538. pvar->Clear();
  539. delete pvar;
  540. pvar = NULL;
  541. THROW_LAST();
  542. }
  543. END_CATCH_ALL
  544. pvar->Clear();
  545. delete pvar;
  546. pvar = NULL;
  547. }
  548. return;
  549. case Fixup:
  550. if (m_prs->GetFieldLength(m_nField-1) == DAO_NULL)
  551. {
  552. // Set the value to PSEUDO NULL and mark the status NULL
  553. SetNullValue(pv, dwColumnType);
  554. m_prs->SetNullFieldStatus(m_nField-1);
  555. }
  556. return;
  557. case AllocCache:
  558. if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
  559. {
  560. CDaoFieldCache* pCache;
  561. // Allocate new storage and add to map
  562. AllocCacheValue(pCache, dwColumnType);
  563. m_prs->m_pMapFieldCache->SetAt(pv, pCache);
  564. }
  565. return;
  566. case StoreField:
  567. if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
  568. {
  569. CDaoFieldCache* pCache = GetCacheValue(m_prs, pv);
  570. // Copy the data to the cache
  571. if (dwBindOptions & AFX_DAO_CACHE_BY_VALUE)
  572. CopyValue(pv, (void*)&pCache->m_pvData, dwColumnType);
  573. else
  574. CopyValue(pv, pCache->m_pvData, dwColumnType);
  575. // Cache the NULL status
  576. if (m_prs->IsFieldStatusNull(m_nField-1))
  577. pCache->m_nStatus |= AFX_DAO_FIELD_FLAG_NULL;
  578. else
  579. pCache->m_nStatus &= ~AFX_DAO_FIELD_FLAG_NULL;
  580. }
  581. return;
  582. case LoadField:
  583. if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
  584. {
  585. CDaoFieldCache* pCache = GetCacheValue(m_prs, pv);
  586. // Copy the data from the cache
  587. if (dwBindOptions & AFX_DAO_CACHE_BY_VALUE)
  588. CopyValue((void*)&pCache->m_pvData, pv, dwColumnType);
  589. else
  590. CopyValue(pCache->m_pvData, pv, dwColumnType);
  591. // Set the NULL status from the cache
  592. if (pCache->m_nStatus & AFX_DAO_FIELD_FLAG_NULL)
  593. m_prs->SetNullFieldStatus(m_nField-1);
  594. else
  595. m_prs->ClearNullFieldStatus(m_nField-1);
  596. }
  597. return;
  598. case SetFieldNull:
  599. // Setting field NOT NULL doesn't require field exchange
  600. if ((m_pvField == NULL && m_nFieldType == outputColumn)
  601. || m_pvField == pv)
  602. {
  603. SetNullValue(pv, dwColumnType);
  604. // Also set the status array if not a parameter
  605. if (m_nFieldType == outputColumn)
  606. m_prs->SetNullFieldStatus(m_nField-1);
  607. #ifdef _DEBUG
  608. m_nFieldFound = m_nField;
  609. #endif
  610. }
  611. return;
  612. case MarkForAddNew:
  613. if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
  614. {
  615. // Don't need to do anything if field marked dirty
  616. if (!m_prs->IsFieldStatusDirty(m_nField-1))
  617. {
  618. // Mark dirty & not NULL if not set to pseudo NULL value
  619. if (!IsNullValue(pv, dwColumnType))
  620. {
  621. m_prs->SetDirtyFieldStatus(m_nField-1);
  622. m_prs->ClearNullFieldStatus(m_nField-1);
  623. }
  624. }
  625. }
  626. return;
  627. case MarkForEdit:
  628. if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
  629. {
  630. // If value not pseudo NULL value, clear NULL status
  631. if (!IsNullValue(pv, dwColumnType))
  632. m_prs->ClearNullFieldStatus(m_nField-1);
  633. // If field already marked dirty, don't need to check cache
  634. if (!m_prs->IsFieldStatusDirty(m_nField-1))
  635. {
  636. CDaoFieldCache* pCache = GetCacheValue(m_prs, pv);
  637. BOOL bNullField = m_prs->IsFieldStatusNull(m_nField-1);
  638. BOOL bNullCache = pCache->m_nStatus & AFX_DAO_FIELD_FLAG_NULL;
  639. void* pvData;
  640. if (dwBindOptions & AFX_DAO_CACHE_BY_VALUE)
  641. pvData = &pCache->m_pvData;
  642. else
  643. pvData = pCache->m_pvData;
  644. // Mark dirty if NULL status differs or value differs
  645. if ( (bNullCache && !bNullField) ||
  646. (!bNullCache && bNullField) ||
  647. CompareValue(pv, pvData, dwColumnType))
  648. {
  649. m_prs->SetDirtyFieldStatus(m_nField-1);
  650. }
  651. }
  652. }
  653. return;
  654. case SetDirtyField:
  655. if (m_prs->IsFieldStatusDirty(m_nField-1))
  656. {
  657. COleVariant* pvar = NULL;
  658. TRY
  659. {
  660. // If field is NULL don't set the value
  661. if (!m_prs->IsFieldStatusNull(m_nField-1))
  662. FillVariant(pv, dwColumnType, &pvar);
  663. else
  664. {
  665. pvar = new COleVariant;
  666. pvar->vt = VT_NULL;
  667. }
  668. // SetFieldValue (put_Collect) doesn't like brackets
  669. // Assumes no brackets if first char not a bracket
  670. LPTSTR lpszModifiedName = NULL;
  671. if (*lpszName == '[')
  672. {
  673. lpszModifiedName = new TCHAR[lstrlen(lpszName) + 1];
  674. // Copy the name with no brackets, and reset lpszName
  675. m_prs->StripBrackets(lpszName, lpszModifiedName);
  676. lpszName = lpszModifiedName;
  677. }
  678. m_prs->SetFieldValue(lpszName, *pvar);
  679. delete lpszModifiedName;
  680. }
  681. CATCH_ALL(e)
  682. {
  683. if (pvar != NULL)
  684. pvar->Clear();
  685. delete pvar;
  686. pvar = NULL;
  687. THROW_LAST();
  688. }
  689. END_CATCH_ALL
  690. pvar->Clear();
  691. delete pvar;
  692. pvar = NULL;
  693. }
  694. return;
  695. default:
  696. ASSERT(FALSE);
  697. return;
  698. }
  699. }
  700. void AFXAPI DFX_Text(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  701. CString& value, int nPreAllocSize, DWORD dwBindOptions)
  702. {
  703. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  704. ++pFX->m_nField: ++pFX->m_nParam;
  705. // Do nothing if op not supported for outputColumn or param type
  706. if (!pFX->IsValidOperation())
  707. return;
  708. DWORD dwDAOType;
  709. #ifdef _UNICODE
  710. dwDAOType = DAO_WCHAR;
  711. #else
  712. dwDAOType = DAO_CHAR;
  713. #endif
  714. switch (pFX->m_nOperation)
  715. {
  716. case CDaoFieldExchange::BindField:
  717. {
  718. // Pre-allocate buffer to prevent needless re-allocations
  719. value.GetBuffer(nPreAllocSize);
  720. value.ReleaseBuffer();
  721. LPDAOCOLUMNBINDING pcb =
  722. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  723. pcb->dwDataType = dwDAOType;
  724. pcb->dwBinding = DAOBINDING_DIRECT | DAOBINDING_CALLBACK;
  725. pcb->dwUser = (DWORD)&value;
  726. pcb->cbDataOffset = (DWORD)DaoStringAllocCallback;
  727. pcb->cbMaxLen = INT_MAX;
  728. }
  729. // Fall through to finish setting up column binding struct
  730. default:
  731. pFX->Default(lpszName, (void*)&value, AFX_RFX_TEXT,
  732. dwBindOptions);
  733. return;
  734. case CDaoFieldExchange::Fixup:
  735. if (pFX->m_prs->m_pulColumnLengths[pFX->m_nField-1] == 0 ||
  736. pFX->m_prs->m_pulColumnLengths[pFX->m_nField-1] == DAO_NULL)
  737. {
  738. // If null or empty string set length zero
  739. value.GetBufferSetLength(0);
  740. }
  741. else
  742. {
  743. // Make sure length correct
  744. value.GetBufferSetLength(
  745. ((pFX->m_prs->m_pulColumnLengths[pFX->m_nField-1])/sizeof(TCHAR))-1);
  746. }
  747. pFX->Default(lpszName, (void*)&value,
  748. AFX_RFX_TEXT, dwBindOptions);
  749. return;
  750. #ifdef _DEBUG
  751. case CDaoFieldExchange::DumpField:
  752. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  753. return;
  754. #endif //_DEBUG
  755. }
  756. }
  757. void AFXAPI DFX_Binary(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  758. CByteArray& value, int nPreAllocSize, DWORD dwBindOptions)
  759. {
  760. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  761. ++pFX->m_nField: ++pFX->m_nParam;
  762. // Do nothing if op not supported for outputColumn or param type
  763. if (!pFX->IsValidOperation())
  764. return;
  765. switch (pFX->m_nOperation)
  766. {
  767. case CDaoFieldExchange::BindField:
  768. {
  769. // Pre-allocate buffer to prevent needless re-allocations
  770. value.SetSize(nPreAllocSize);
  771. LPDAOCOLUMNBINDING pcb =
  772. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  773. pcb->dwDataType = DAO_BYTES;
  774. pcb->dwBinding = DAOBINDING_DIRECT | DAOBINDING_CALLBACK;
  775. pcb->dwUser = (DWORD)&value;
  776. pcb->cbDataOffset = (ULONG)DaoBinaryAllocCallback;
  777. pcb->cbMaxLen = INT_MAX;
  778. }
  779. // Fall through to finish setting up column binding struct
  780. default:
  781. pFX->Default(lpszName, (void*)&value, AFX_RFX_BINARY,
  782. dwBindOptions);
  783. return;
  784. #ifdef _DEBUG
  785. case CDaoFieldExchange::DumpField:
  786. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  787. return;
  788. #endif //_DEBUG
  789. }
  790. }
  791. void AFXAPI DFX_LongBinary(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  792. CLongBinary& value, DWORD dwPreAllocSize, DWORD dwBindOptions)
  793. {
  794. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  795. ++pFX->m_nField: ++pFX->m_nParam;
  796. // Do nothing if op not supported for outputColumn or param type
  797. if (!pFX->IsValidOperation())
  798. return;
  799. switch (pFX->m_nOperation)
  800. {
  801. case CDaoFieldExchange::BindField:
  802. {
  803. // Pre-allocate buffer to prevent needless re-allocations
  804. AllocLongBinary(value, dwPreAllocSize);
  805. LPDAOCOLUMNBINDING pcb =
  806. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  807. pcb->dwDataType = DAO_BYTES;
  808. pcb->dwBinding = DAOBINDING_DIRECT | DAOBINDING_CALLBACK;
  809. pcb->dwUser = (DWORD)&value;
  810. pcb->cbDataOffset = (DWORD)DaoLongBinaryAllocCallback;
  811. pcb->cbMaxLen = ULONG_MAX;
  812. }
  813. // Fall through to finish setting up column binding struct
  814. default:
  815. pFX->Default(lpszName, (void*)&value,
  816. AFX_RFX_LONGBINARY, dwBindOptions);
  817. return;
  818. case CDaoFieldExchange::Fixup:
  819. // Unlock data locked in DaoLongBinaryAllocCallback
  820. if (value.m_dwDataLength != 0)
  821. ::GlobalUnlock(value.m_hData);
  822. pFX->Default(lpszName, (void*)&value,
  823. AFX_RFX_LONGBINARY, dwBindOptions);
  824. return;
  825. #ifdef _DEBUG
  826. case CDaoFieldExchange::DumpField:
  827. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  828. return;
  829. #endif //_DEBUG
  830. }
  831. }
  832. void AFXAPI DFX_Bool(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  833. BOOL& value, DWORD dwBindOptions)
  834. {
  835. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  836. ++pFX->m_nField: ++pFX->m_nParam;
  837. // Do nothing if op not supported for outputColumn or param type
  838. if (!pFX->IsValidOperation())
  839. return;
  840. // Mark as CACHE_BY_VALUE (size <= sizeof(void*))
  841. dwBindOptions |= AFX_DAO_CACHE_BY_VALUE;
  842. switch (pFX->m_nOperation)
  843. {
  844. case CDaoFieldExchange::BindField:
  845. {
  846. LPDAOCOLUMNBINDING pcb =
  847. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  848. pcb->dwDataType = DAO_BOOL;
  849. pcb->dwBinding = DAOBINDING_DIRECT;
  850. pcb->cbDataOffset = (DWORD)&value;
  851. pcb->dwUser = 0;
  852. pcb->cbMaxLen = sizeof(value);
  853. pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
  854. }
  855. // Fall through to finish setting up column binding struct
  856. default:
  857. pFX->Default(lpszName, (void*)&value, AFX_RFX_BOOL,
  858. dwBindOptions);
  859. return;
  860. case CDaoFieldExchange::Fixup:
  861. // Convert BOOL value from AFX_DAO_TRUE/FALSE to TRUE/FALSE
  862. value = (value != AFX_DAO_FALSE);
  863. pFX->Default(lpszName, (void*)&value,
  864. AFX_RFX_BOOL, dwBindOptions);
  865. return;
  866. #ifdef _DEBUG
  867. case CDaoFieldExchange::DumpField:
  868. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  869. return;
  870. #endif //_DEBUG
  871. }
  872. }
  873. void AFXAPI DFX_Byte(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  874. BYTE& value, DWORD dwBindOptions)
  875. {
  876. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  877. ++pFX->m_nField: ++pFX->m_nParam;
  878. // Do nothing if op not supported for outputColumn or param type
  879. if (!pFX->IsValidOperation())
  880. return;
  881. // Mark as CACHE_BY_VALUE (size <= sizeof(void*))
  882. dwBindOptions |= AFX_DAO_CACHE_BY_VALUE;
  883. switch (pFX->m_nOperation)
  884. {
  885. case CDaoFieldExchange::BindField:
  886. {
  887. LPDAOCOLUMNBINDING pcb =
  888. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  889. pcb->dwDataType = DAO_BYTE;
  890. pcb->dwBinding = DAOBINDING_DIRECT;
  891. pcb->cbDataOffset = (DWORD)&value;
  892. pcb->dwUser = 0;
  893. pcb->cbMaxLen = sizeof(value);
  894. pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
  895. }
  896. // Fall through to finish setting up column binding struct
  897. default:
  898. pFX->Default(lpszName, (void*)&value, AFX_RFX_BYTE,
  899. dwBindOptions);
  900. return;
  901. #ifdef _DEBUG
  902. case CDaoFieldExchange::DumpField:
  903. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  904. return;
  905. #endif //_DEBUG
  906. }
  907. }
  908. void AFXAPI DFX_Short(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  909. short& value, DWORD dwBindOptions)
  910. {
  911. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  912. ++pFX->m_nField: ++pFX->m_nParam;
  913. // Do nothing if op not supported for outputColumn or param type
  914. if (!pFX->IsValidOperation())
  915. return;
  916. // Mark as CACHE_BY_VALUE (size <= sizeof(void*))
  917. dwBindOptions |= AFX_DAO_CACHE_BY_VALUE;
  918. switch (pFX->m_nOperation)
  919. {
  920. case CDaoFieldExchange::BindField:
  921. {
  922. LPDAOCOLUMNBINDING pcb =
  923. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  924. pcb->dwDataType = DAO_I2;
  925. pcb->dwBinding = DAOBINDING_DIRECT;
  926. pcb->cbDataOffset = (DWORD)&value;
  927. pcb->dwUser = 0;
  928. pcb->cbMaxLen = sizeof(value);
  929. pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
  930. }
  931. // Fall through to finish setting up column binding struct
  932. default:
  933. pFX->Default(lpszName, (void*)&value, AFX_RFX_SHORT,
  934. dwBindOptions);
  935. return;
  936. #ifdef _DEBUG
  937. case CDaoFieldExchange::DumpField:
  938. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  939. return;
  940. #endif //_DEBUG
  941. }
  942. }
  943. void AFXAPI DFX_Long(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  944. long& value, DWORD dwBindOptions)
  945. {
  946. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  947. ++pFX->m_nField: ++pFX->m_nParam;
  948. // Do nothing if op not supported for outputColumn or param type
  949. if (!pFX->IsValidOperation())
  950. return;
  951. // Mark as CACHE_BY_VALUE (size <= sizeof(void*))
  952. dwBindOptions |= AFX_DAO_CACHE_BY_VALUE;
  953. switch (pFX->m_nOperation)
  954. {
  955. case CDaoFieldExchange::BindField:
  956. {
  957. LPDAOCOLUMNBINDING pcb =
  958. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  959. pcb->dwDataType = DAO_I4;
  960. pcb->dwBinding = DAOBINDING_DIRECT;
  961. pcb->cbDataOffset = (DWORD)&value;
  962. pcb->dwUser = 0;
  963. pcb->cbMaxLen = sizeof(value);
  964. pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
  965. }
  966. // Fall through to finish setting up column binding struct
  967. default:
  968. pFX->Default(lpszName, (void*)&value, AFX_RFX_LONG,
  969. dwBindOptions);
  970. return;
  971. #ifdef _DEBUG
  972. case CDaoFieldExchange::DumpField:
  973. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  974. return;
  975. #endif //_DEBUG
  976. }
  977. }
  978. void AFXAPI DFX_Currency(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  979. COleCurrency& value, DWORD dwBindOptions)
  980. {
  981. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  982. ++pFX->m_nField: ++pFX->m_nParam;
  983. // Do nothing if op not supported for outputColumn or param type
  984. if (!pFX->IsValidOperation())
  985. return;
  986. switch (pFX->m_nOperation)
  987. {
  988. case CDaoFieldExchange::BindField:
  989. {
  990. LPDAOCOLUMNBINDING pcb =
  991. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  992. pcb->dwDataType = DAO_CURRENCY;
  993. pcb->dwBinding = DAOBINDING_DIRECT;
  994. pcb->cbDataOffset = (DWORD)&value.m_cur;
  995. pcb->dwUser = 0;
  996. pcb->cbMaxLen = sizeof(CURRENCY);
  997. pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
  998. // Finish setting up column binding struct
  999. pFX->Default(lpszName, (void*)&value, AFX_RFX_CURRENCY,
  1000. dwBindOptions);
  1001. return;
  1002. }
  1003. case CDaoFieldExchange::Fixup:
  1004. // Must reset the valid currency flag
  1005. if (pFX->m_prs->GetFieldLength(pFX->m_nField-1) == DAO_NULL)
  1006. value.SetStatus(COleCurrency::null);
  1007. else
  1008. value.SetStatus(COleCurrency::valid);
  1009. // Fall through to reset the NULL status
  1010. default:
  1011. pFX->Default(lpszName, (void*)&value, AFX_RFX_CURRENCY,
  1012. dwBindOptions);
  1013. return;
  1014. #ifdef _DEBUG
  1015. case CDaoFieldExchange::DumpField:
  1016. *pFX->m_pdcDump << "\n" << lpszName << ":" << value;
  1017. return;
  1018. #endif //_DEBUG
  1019. }
  1020. }
  1021. void AFXAPI DFX_Single(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  1022. float& value, DWORD dwBindOptions)
  1023. {
  1024. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  1025. ++pFX->m_nField: ++pFX->m_nParam;
  1026. // Do nothing if op not supported for outputColumn or param type
  1027. if (!pFX->IsValidOperation())
  1028. return;
  1029. // Mark as CACHE_BY_VALUE (size <= sizeof(void*))
  1030. dwBindOptions |= AFX_DAO_CACHE_BY_VALUE;
  1031. switch (pFX->m_nOperation)
  1032. {
  1033. case CDaoFieldExchange::BindField:
  1034. {
  1035. LPDAOCOLUMNBINDING pcb =
  1036. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  1037. pcb->dwDataType = DAO_R4;
  1038. pcb->dwBinding = DAOBINDING_DIRECT;
  1039. pcb->cbDataOffset = (DWORD)&value;
  1040. pcb->dwUser = 0;
  1041. pcb->cbMaxLen = sizeof(value);
  1042. pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
  1043. }
  1044. // Fall through to finish setting up column binding struct
  1045. default:
  1046. pFX->Default(lpszName, (void*)&value, AFX_RFX_SINGLE,
  1047. dwBindOptions);
  1048. return;
  1049. #ifdef _DEBUG
  1050. case CDaoFieldExchange::DumpField:
  1051. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  1052. return;
  1053. #endif //_DEBUG
  1054. }
  1055. }
  1056. void AFXAPI DFX_Double(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  1057. double& value, DWORD dwBindOptions)
  1058. {
  1059. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  1060. ++pFX->m_nField: ++pFX->m_nParam;
  1061. // Do nothing if op not supported for outputColumn or param type
  1062. if (!pFX->IsValidOperation())
  1063. return;
  1064. switch (pFX->m_nOperation)
  1065. {
  1066. case CDaoFieldExchange::BindField:
  1067. {
  1068. LPDAOCOLUMNBINDING pcb =
  1069. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  1070. pcb->dwDataType = DAO_R8;
  1071. pcb->dwBinding = DAOBINDING_DIRECT;
  1072. pcb->cbDataOffset = (DWORD)&value;
  1073. pcb->dwUser = 0;
  1074. pcb->cbMaxLen = sizeof(value);
  1075. pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
  1076. }
  1077. // Fall through to finish setting up column binding struct
  1078. default:
  1079. pFX->Default(lpszName, (void*)&value, AFX_RFX_DOUBLE,
  1080. dwBindOptions);
  1081. return;
  1082. #ifdef _DEBUG
  1083. case CDaoFieldExchange::DumpField:
  1084. *pFX->m_pdcDump << "\n" << lpszName << " = " << value;
  1085. return;
  1086. #endif //_DEBUG
  1087. }
  1088. }
  1089. void AFXAPI DFX_DateTime(CDaoFieldExchange* pFX, LPCTSTR lpszName,
  1090. COleDateTime& value, DWORD dwBindOptions)
  1091. {
  1092. (pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
  1093. ++pFX->m_nField: ++pFX->m_nParam;
  1094. // Do nothing if op not supported for outputColumn or param type
  1095. if (!pFX->IsValidOperation())
  1096. return;
  1097. switch (pFX->m_nOperation)
  1098. {
  1099. case CDaoFieldExchange::BindField:
  1100. {
  1101. LPDAOCOLUMNBINDING pcb =
  1102. &pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
  1103. pcb->dwDataType = DAO_DATE;
  1104. pcb->dwBinding = DAOBINDING_DIRECT;
  1105. pcb->cbDataOffset = (DWORD)&value.m_dt;
  1106. pcb->dwUser = 0;
  1107. pcb->cbMaxLen = sizeof(DATE);
  1108. pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
  1109. // Finish setting up column binding struct
  1110. pFX->Default(lpszName,(void*)&value, AFX_RFX_DATE,
  1111. dwBindOptions);
  1112. return;
  1113. }
  1114. case CDaoFieldExchange::Fixup:
  1115. // Must reset the valid currency flag
  1116. if (pFX->m_prs->GetFieldLength(pFX->m_nField-1) == DAO_NULL)
  1117. value.SetStatus(COleDateTime::null);
  1118. else
  1119. value.SetStatus(COleDateTime::valid);
  1120. // Fall through to reset the NULL status
  1121. default:
  1122. pFX->Default(lpszName, (void*)&value, AFX_RFX_DATE,
  1123. dwBindOptions);
  1124. return;
  1125. #ifdef _DEBUG
  1126. case CDaoFieldExchange::DumpField:
  1127. *pFX->m_pdcDump << "\n" << lpszName << ":" << value;
  1128. return;
  1129. #endif //_DEBUG
  1130. }
  1131. }
  1132. //////////////////////////////////////////////////////////////////////////////
  1133. // DAO memory allocation callback helpers
  1134. STDAPI DaoStringAllocCallback(DWORD dwLen, DWORD pData, void** ppv)
  1135. {
  1136. LPTSTR lpsz;
  1137. CString* pstr = (CString*)pData;
  1138. #ifndef _UNICODE
  1139. // If using ANSI DAO interfaces, DAO reports field length
  1140. // rather than data length. In this case there will not be space
  1141. // for NULL terminator if data length equals field length. Make room.
  1142. dwLen++;
  1143. #endif
  1144. TRY
  1145. {
  1146. // Only re-allocate if necessary
  1147. lpsz = pstr->GetBufferSetLength(dwLen/sizeof(TCHAR));
  1148. *ppv = (void*)(dwLen > 0 ? lpsz : NULL);
  1149. }
  1150. CATCH_ALL(e)
  1151. {
  1152. e->Delete();
  1153. return E_OUTOFMEMORY;
  1154. }
  1155. END_CATCH_ALL
  1156. return S_OK;
  1157. }
  1158. STDAPI DaoBinaryAllocCallback(DWORD dwLen, DWORD pData, void** ppv)
  1159. {
  1160. CByteArray* pByteArray = (CByteArray*)pData;
  1161. TRY
  1162. {
  1163. // Only re-allocate if necessary
  1164. pByteArray->SetSize(dwLen);
  1165. *ppv = (void*)(dwLen > 0 ? &((*pByteArray)[0]) : NULL);
  1166. }
  1167. CATCH_ALL(e)
  1168. {
  1169. // Only exceptions thrown should be CMemoryException
  1170. e->Delete();
  1171. return E_OUTOFMEMORY;
  1172. }
  1173. END_CATCH_ALL
  1174. return S_OK;
  1175. }
  1176. STDAPI DaoLongBinaryAllocCallback(DWORD dwLen, DWORD pData, void** ppv)
  1177. {
  1178. CLongBinary* pLongBinary = (CLongBinary*)pData;
  1179. TRY
  1180. {
  1181. AllocLongBinary(*pLongBinary, dwLen);
  1182. }
  1183. CATCH_ALL(e)
  1184. {
  1185. // Only exception is memory exception, just pass back error.
  1186. DELETE_EXCEPTION(e);
  1187. return E_OUTOFMEMORY;
  1188. }
  1189. END_CATCH_ALL
  1190. if (pLongBinary->m_dwDataLength != 0)
  1191. {
  1192. const BYTE* pByte;
  1193. pByte = (const BYTE*)::GlobalLock(pLongBinary->m_hData);
  1194. // If mem can't be locked, free up and return error
  1195. if (pByte == NULL)
  1196. {
  1197. ::GlobalFree(pLongBinary->m_hData);
  1198. pLongBinary->m_hData = NULL;
  1199. return E_OUTOFMEMORY;
  1200. }
  1201. *ppv = (void*)pByte;
  1202. }
  1203. else
  1204. *ppv = NULL;
  1205. return S_OK;
  1206. }
  1207. void AFX_CDECL AllocLongBinary(CLongBinary& lb, DWORD dwDataLength)
  1208. {
  1209. if (lb.m_hData == NULL)
  1210. {
  1211. if (dwDataLength > 0)
  1212. {
  1213. // Alloc memory, return error if not possible
  1214. lb.m_hData = ::GlobalAlloc(GMEM_MOVEABLE, dwDataLength);
  1215. if (lb.m_hData == NULL)
  1216. AfxThrowMemoryException();
  1217. }
  1218. }
  1219. else if (::GlobalSize(lb.m_hData) < dwDataLength)
  1220. {
  1221. // Save the old address in case ReAlloc fails
  1222. HGLOBAL hOldData = lb.m_hData;
  1223. // Alloc more mem, free up mem and throw exception if not possible
  1224. lb.m_hData = ::GlobalReAlloc(hOldData, dwDataLength, GMEM_MOVEABLE);
  1225. if (lb.m_hData == NULL)
  1226. {
  1227. lb.m_hData = hOldData;
  1228. AfxThrowMemoryException();
  1229. }
  1230. }
  1231. lb.m_dwDataLength = dwDataLength;
  1232. }
  1233. //////////////////////////////////////////////////////////////////////////////
  1234. // Inline function declarations expanded out-of-line
  1235. #ifndef _AFX_ENABLE_INLINES
  1236. static char _szAfxDaoInl[] = "afxdao.inl";
  1237. #undef THIS_FILE
  1238. #define THIS_FILE _szAfxDaoInl
  1239. #define _AFXDAODFX_INLINE
  1240. #include "afxdao.inl"
  1241. #endif
  1242. #ifdef AFX_INIT_SEG
  1243. #pragma code_seg(AFX_INIT_SEG)
  1244. #endif
  1245. /////////////////////////////////////////////////////////////////////////////