mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1480 lines
32 KiB
1480 lines
32 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "math.h"
|
|
|
|
#ifdef AFX_DB_SEG
|
|
#pragma code_seg(AFX_DB_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Helpers
|
|
|
|
// Helpers for floating point operations
|
|
static const float afxFloatPseudoNull = AFX_RFX_SINGLE_PSEUDO_NULL;
|
|
static const double afxDoublePseudoNull = AFX_RFX_DOUBLE_PSEUDO_NULL;
|
|
|
|
// Long binary allocation helper
|
|
void AFX_CDECL AllocLongBinary(CLongBinary& lb, DWORD dwDataLength);
|
|
|
|
// Memory allocation callbacks used by ICDAOGetRows
|
|
STDAPI DaoStringAllocCallback(DWORD dwLen, DWORD pData, void** ppv);
|
|
STDAPI DaoBinaryAllocCallback(DWORD dwLen, DWORD pData, void** ppv);
|
|
STDAPI DaoLongBinaryAllocCallback(DWORD dwLen, DWORD pData, void** ppv);
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CDaoFieldExchange
|
|
|
|
CDaoFieldExchange::CDaoFieldExchange(UINT nOperation,
|
|
CDaoRecordset* prs, void* pvField)
|
|
{
|
|
ASSERT(nOperation < MaxDFXOperation);
|
|
|
|
m_nFieldType = none;
|
|
m_nOperation = nOperation;
|
|
m_prs = prs;
|
|
m_pvField = pvField;
|
|
m_nField = 0;
|
|
m_nParam = 0;
|
|
}
|
|
|
|
BOOL CDaoFieldExchange::IsValidOperation()
|
|
{
|
|
if (m_nOperation >= MaxDFXOperation)
|
|
{
|
|
// Invalid operation
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
// Operations valid for both field types
|
|
#ifdef _DEBUG
|
|
if (m_nOperation == DumpField || m_nOperation == SetFieldNull)
|
|
return TRUE;
|
|
#endif
|
|
|
|
// Operations only valid for outputColumn OR param types
|
|
if ((m_nOperation == AddToParameterList) ||
|
|
(m_nOperation == BindParam))
|
|
return (m_nFieldType == param);
|
|
else
|
|
return (m_nFieldType == outputColumn);
|
|
}
|
|
|
|
void CDaoFieldExchange::AppendParamType(CString& strParamList,
|
|
DWORD dwParamType)
|
|
{
|
|
switch (dwParamType)
|
|
{
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
|
|
case AFX_RFX_TEXT:
|
|
strParamList += " Text";
|
|
break;
|
|
|
|
case AFX_RFX_BINARY:
|
|
strParamList += " LongBinary";
|
|
break;
|
|
|
|
case AFX_RFX_LONGBINARY:
|
|
strParamList += " LongBinary";
|
|
break;
|
|
|
|
case AFX_RFX_BOOL:
|
|
strParamList += " Bit";
|
|
break;
|
|
|
|
case AFX_RFX_BYTE:
|
|
strParamList += " Byte";
|
|
break;
|
|
|
|
case AFX_RFX_SHORT:
|
|
strParamList += " Short";
|
|
break;
|
|
|
|
case AFX_RFX_LONG:
|
|
strParamList += " Long";
|
|
break;
|
|
|
|
case AFX_RFX_CURRENCY:
|
|
strParamList += " Currency";
|
|
break;
|
|
|
|
case AFX_RFX_SINGLE:
|
|
strParamList += " IEEESingle";
|
|
break;
|
|
|
|
case AFX_RFX_DOUBLE:
|
|
strParamList += " IEEEDouble";
|
|
break;
|
|
|
|
case AFX_RFX_DATE:
|
|
strParamList += " DateTime";
|
|
break;
|
|
}
|
|
}
|
|
|
|
CDaoFieldCache* CDaoFieldExchange::GetCacheValue(CDaoRecordset* prs, void* pv)
|
|
{
|
|
void* pvCache;
|
|
|
|
// Lookup storage locations
|
|
if (!prs->m_pMapFieldCache->Lookup(pv, pvCache))
|
|
AfxThrowDaoException(AFX_DAO_ERROR_DFX_BIND);
|
|
return (CDaoFieldCache*)pvCache;
|
|
}
|
|
|
|
void CDaoFieldExchange::SetNullValue(void* pv, DWORD dwDataType)
|
|
{
|
|
switch (dwDataType)
|
|
{
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
|
|
case AFX_RFX_TEXT:
|
|
((CString*)pv)->Empty();
|
|
break;
|
|
|
|
case AFX_RFX_BINARY:
|
|
((CByteArray*)pv)->SetSize(0);
|
|
break;
|
|
|
|
case AFX_RFX_LONGBINARY:
|
|
((CLongBinary*)pv)->m_dwDataLength = 0;
|
|
break;
|
|
|
|
case AFX_RFX_BOOL:
|
|
*(BOOL*)pv = AFX_RFX_BOOL_PSEUDO_NULL;
|
|
break;
|
|
|
|
case AFX_RFX_BYTE:
|
|
*(BYTE*)pv = AFX_RFX_BYTE_PSEUDO_NULL;
|
|
break;
|
|
|
|
case AFX_RFX_SHORT:
|
|
*(short*)pv = AFX_RFX_SHORT_PSEUDO_NULL;
|
|
break;
|
|
|
|
case AFX_RFX_LONG:
|
|
*(long*)pv = AFX_RFX_LONG_PSEUDO_NULL;
|
|
break;
|
|
|
|
case AFX_RFX_CURRENCY:
|
|
((COleCurrency*)pv)->SetStatus(COleCurrency::null);
|
|
break;
|
|
|
|
case AFX_RFX_SINGLE:
|
|
*(float*)pv = afxFloatPseudoNull;
|
|
break;
|
|
|
|
case AFX_RFX_DOUBLE:
|
|
*(double*)pv = afxDoublePseudoNull;
|
|
break;
|
|
|
|
case AFX_RFX_DATE:
|
|
((COleDateTime*)pv)->SetStatus(COleDateTime::null);
|
|
break;
|
|
}
|
|
}
|
|
|
|
BOOL CDaoFieldExchange::IsNullValue(void* pv, DWORD dwDataType)
|
|
{
|
|
BOOL bNull = FALSE;
|
|
|
|
switch (dwDataType)
|
|
{
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
|
|
case AFX_RFX_TEXT:
|
|
if (((CString*)pv)->IsEmpty())
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_BINARY:
|
|
if (((CByteArray*)pv)->GetSize() == 0)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_LONGBINARY:
|
|
if (((CLongBinary*)pv)->m_dwDataLength == 0)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_BOOL:
|
|
if (*(BOOL*)pv == AFX_RFX_BOOL_PSEUDO_NULL)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_BYTE:
|
|
if (*(BYTE*)pv == AFX_RFX_BYTE_PSEUDO_NULL)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_SHORT:
|
|
if (*(short*)pv == AFX_RFX_SHORT_PSEUDO_NULL)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_LONG:
|
|
if (*(long*)pv == AFX_RFX_LONG_PSEUDO_NULL)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_CURRENCY:
|
|
if (((COleCurrency*)pv)->GetStatus() == COleCurrency::null)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_SINGLE:
|
|
if (*(float*)pv == afxFloatPseudoNull)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_DOUBLE:
|
|
if (*(double*)pv == afxDoublePseudoNull)
|
|
bNull = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_DATE:
|
|
if (((COleDateTime*)pv)->GetStatus() == COleDateTime::null)
|
|
bNull = TRUE;
|
|
break;
|
|
}
|
|
|
|
return bNull;
|
|
}
|
|
|
|
void CDaoFieldExchange::AllocCacheValue(CDaoFieldCache*& pCache,
|
|
DWORD dwDataType)
|
|
{
|
|
// Initialize a new field cache
|
|
pCache = new CDaoFieldCache;
|
|
pCache->m_nStatus = 0;
|
|
|
|
switch (dwDataType)
|
|
{
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
|
|
case AFX_RFX_TEXT:
|
|
pCache->m_pvData = new CString();
|
|
pCache->m_nDataType = AFX_RFX_TEXT;
|
|
break;
|
|
|
|
case AFX_RFX_BINARY:
|
|
pCache->m_pvData = new CByteArray();
|
|
pCache->m_nDataType = AFX_RFX_BINARY;
|
|
break;
|
|
|
|
case AFX_RFX_LONGBINARY:
|
|
pCache->m_pvData = new CLongBinary();
|
|
pCache->m_nDataType = AFX_RFX_LONGBINARY;
|
|
break;
|
|
|
|
case AFX_RFX_BOOL:
|
|
pCache->m_pvData = new BOOL;
|
|
pCache->m_nDataType = AFX_RFX_BOOL;
|
|
break;
|
|
|
|
case AFX_RFX_BYTE:
|
|
pCache->m_pvData = new BYTE;
|
|
pCache->m_nDataType = AFX_RFX_BYTE;
|
|
break;
|
|
|
|
case AFX_RFX_SHORT:
|
|
pCache->m_pvData = new short;
|
|
pCache->m_nDataType = AFX_RFX_SHORT;
|
|
break;
|
|
|
|
case AFX_RFX_LONG:
|
|
pCache->m_pvData = new long;
|
|
pCache->m_nDataType = AFX_RFX_LONG;
|
|
break;
|
|
|
|
case AFX_RFX_CURRENCY:
|
|
pCache->m_pvData = new COleCurrency();
|
|
pCache->m_nDataType = AFX_RFX_CURRENCY;
|
|
break;
|
|
|
|
case AFX_RFX_SINGLE:
|
|
pCache->m_pvData = new float;
|
|
pCache->m_nDataType = AFX_RFX_SINGLE;
|
|
break;
|
|
|
|
case AFX_RFX_DOUBLE:
|
|
pCache->m_pvData = new double;
|
|
pCache->m_nDataType = AFX_RFX_DOUBLE;
|
|
break;
|
|
|
|
case AFX_RFX_DATE:
|
|
pCache->m_pvData = new COleDateTime();
|
|
pCache->m_nDataType = AFX_RFX_DATE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CDaoFieldExchange::DeleteCacheValue(CDaoFieldCache* pCache,
|
|
DWORD dwDataType)
|
|
{
|
|
switch (dwDataType)
|
|
{
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
|
|
case AFX_RFX_TEXT:
|
|
delete (CString*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_BINARY:
|
|
delete (CByteArray*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_LONGBINARY:
|
|
delete (CLongBinary*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_BOOL:
|
|
delete (BOOL*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_BYTE:
|
|
delete (BYTE*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_SHORT:
|
|
delete (short*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_LONG:
|
|
delete (long*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_CURRENCY:
|
|
delete (COleCurrency*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_SINGLE:
|
|
delete (float*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_DOUBLE:
|
|
delete (double*)pCache->m_pvData;
|
|
break;
|
|
|
|
case AFX_RFX_DATE:
|
|
delete (COleDateTime*)pCache->m_pvData;
|
|
break;
|
|
}
|
|
|
|
delete pCache;
|
|
pCache = NULL;
|
|
}
|
|
|
|
void CDaoFieldExchange::CopyValue(void* pvSrc, void* pvDest,
|
|
DWORD dwDataType)
|
|
{
|
|
switch (dwDataType)
|
|
{
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
|
|
case AFX_RFX_TEXT:
|
|
*(CString*)pvDest = *(CString*)pvSrc;
|
|
break;
|
|
|
|
case AFX_RFX_BINARY:
|
|
((CByteArray*)pvDest)->Copy(*(CByteArray*)pvSrc);
|
|
break;
|
|
|
|
case AFX_RFX_LONGBINARY:
|
|
{
|
|
CLongBinary* pLongBinarySrc = (CLongBinary*)pvSrc;
|
|
CLongBinary* pLongBinaryDest = (CLongBinary*)pvDest;
|
|
|
|
// Reallocate memory in destination if necessary
|
|
AllocLongBinary(*pLongBinaryDest, pLongBinarySrc->m_dwDataLength);
|
|
pLongBinaryDest->m_dwDataLength =
|
|
pLongBinarySrc->m_dwDataLength;
|
|
|
|
BYTE* pbSrc = (BYTE*)::GlobalLock(pLongBinarySrc->m_hData);
|
|
BYTE* pbDest = (BYTE*)::GlobalLock(pLongBinaryDest->m_hData);
|
|
memcpy(pbDest, pbSrc, pLongBinarySrc->m_dwDataLength);
|
|
::GlobalUnlock(pLongBinarySrc->m_hData);
|
|
::GlobalUnlock(pLongBinaryDest->m_hData);
|
|
}
|
|
break;
|
|
|
|
case AFX_RFX_BOOL:
|
|
*(BOOL*)pvDest = *(BOOL*)pvSrc;
|
|
break;
|
|
|
|
case AFX_RFX_BYTE:
|
|
*(BYTE*)pvDest = *(BYTE*)pvSrc;
|
|
break;
|
|
|
|
case AFX_RFX_SHORT:
|
|
*(short*)pvDest = *(short*)pvSrc;
|
|
break;
|
|
|
|
case AFX_RFX_LONG:
|
|
*(long*)pvDest = *(long*)pvSrc;
|
|
break;
|
|
|
|
case AFX_RFX_CURRENCY:
|
|
*(COleCurrency*)pvDest = *(COleCurrency*)pvSrc;
|
|
break;
|
|
|
|
case AFX_RFX_SINGLE:
|
|
*(float*)pvDest = *(float*)pvSrc;
|
|
break;
|
|
|
|
case AFX_RFX_DOUBLE:
|
|
*(double*)pvDest = *(double*)pvSrc;
|
|
break;
|
|
|
|
case AFX_RFX_DATE:
|
|
*(COleDateTime*)pvDest = *(COleDateTime*)pvSrc;
|
|
break;
|
|
}
|
|
}
|
|
|
|
BOOL CDaoFieldExchange::CompareValue(void* pvSrc, void* pvDest,
|
|
DWORD dwDataType)
|
|
{
|
|
BOOL bDirty = FALSE;
|
|
|
|
switch (dwDataType)
|
|
{
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
|
|
case AFX_RFX_TEXT:
|
|
if (*(CString*)pvDest != *(CString*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_BINARY:
|
|
{
|
|
CByteArray* pByteArraySrc = (CByteArray*)pvSrc;
|
|
CByteArray* pByteArrayDest = (CByteArray*)pvDest;
|
|
int nSize = pByteArraySrc->GetSize();
|
|
|
|
if (memcmp(&pByteArrayDest[0], &pByteArraySrc[0], nSize) != 0)
|
|
bDirty = TRUE;
|
|
}
|
|
break;
|
|
|
|
case AFX_RFX_LONGBINARY:
|
|
{
|
|
CLongBinary* pLongBinarySrc = (CLongBinary*)pvSrc;
|
|
CLongBinary* pLongBinaryDest = (CLongBinary*)pvDest;
|
|
|
|
BYTE* pbSrc = (BYTE*)::GlobalLock(pLongBinarySrc->m_hData);
|
|
BYTE* pbDest = (BYTE*)::GlobalLock(pLongBinaryDest->m_hData);
|
|
|
|
if (memcmp(pbDest, pbSrc, pLongBinarySrc->m_dwDataLength) != 0)
|
|
bDirty = TRUE;
|
|
|
|
::GlobalUnlock(pLongBinarySrc->m_hData);
|
|
::GlobalUnlock(pLongBinaryDest->m_hData);
|
|
}
|
|
break;
|
|
|
|
case AFX_RFX_BOOL:
|
|
if (*(BOOL*)pvDest != *(BOOL*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_BYTE:
|
|
if (*(BYTE*)pvDest != *(BYTE*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_SHORT:
|
|
if (*(short*)pvDest != *(short*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_LONG:
|
|
if (*(long*)pvDest != *(long*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_CURRENCY:
|
|
if (*(COleCurrency*)pvDest != *(COleCurrency*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_SINGLE:
|
|
if (*(float*)pvDest != *(float*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_DOUBLE:
|
|
if (*(double*)pvDest != *(double*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
|
|
case AFX_RFX_DATE:
|
|
if (*(COleDateTime*)pvDest != *(COleDateTime*)pvSrc)
|
|
bDirty = TRUE;
|
|
break;
|
|
}
|
|
|
|
return bDirty;
|
|
}
|
|
|
|
void CDaoFieldExchange::FillVariant(void* pvValue, DWORD dwDataType,
|
|
COleVariant** ppVar)
|
|
{
|
|
COleVariant* pVar;
|
|
|
|
if (dwDataType == AFX_RFX_TEXT)
|
|
pVar = new COleVariant(*(CString*)pvValue, VT_BSTRT);
|
|
else if (dwDataType == AFX_RFX_BOOL)
|
|
pVar = new COleVariant(*(long*)pvValue, VT_BOOL);
|
|
else
|
|
{
|
|
pVar = new COleVariant;
|
|
|
|
switch (dwDataType)
|
|
{
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
|
|
case AFX_RFX_BINARY:
|
|
*pVar = *(CByteArray*)pvValue;
|
|
break;
|
|
|
|
case AFX_RFX_LONGBINARY:
|
|
*pVar = *(CLongBinary*)pvValue;
|
|
break;
|
|
|
|
case AFX_RFX_BYTE:
|
|
*pVar = *(BYTE*)pvValue;
|
|
break;
|
|
|
|
case AFX_RFX_SHORT:
|
|
*pVar = *(short*)pvValue;
|
|
break;
|
|
|
|
case AFX_RFX_LONG:
|
|
*pVar = *(long*)pvValue;
|
|
break;
|
|
|
|
case AFX_RFX_CURRENCY:
|
|
*pVar = *(COleCurrency*)pvValue;
|
|
break;
|
|
|
|
case AFX_RFX_SINGLE:
|
|
*pVar = *(float*)pvValue;
|
|
break;
|
|
|
|
case AFX_RFX_DOUBLE:
|
|
*pVar = *(double*)pvValue;
|
|
break;
|
|
|
|
case AFX_RFX_DATE:
|
|
*pVar = *(COleDateTime*)pvValue;
|
|
}
|
|
}
|
|
|
|
*ppVar = pVar;
|
|
}
|
|
|
|
// Default implementation for RFX functions
|
|
void CDaoFieldExchange::Default(LPCTSTR lpszName, void* pv,
|
|
DWORD dwColumnType, DWORD dwBindOptions)
|
|
{
|
|
switch (m_nOperation)
|
|
{
|
|
case AddToParameterList:
|
|
if (m_nParam != 1)
|
|
m_prs->m_strSQL += ",";
|
|
m_prs->m_strSQL += lpszName;
|
|
AppendParamType(m_prs->m_strSQL, dwColumnType);
|
|
return;
|
|
|
|
case AddToSelectList:
|
|
if (m_nField != 1)
|
|
m_prs->m_strSQL += ",";
|
|
m_prs->m_strSQL += lpszName;
|
|
return;
|
|
|
|
case BindField:
|
|
{
|
|
// Query parser needs "[" & "]", GetRows can't tolerate them.
|
|
LPTSTR lpszNoBracketName = new TCHAR[_tcslen(lpszName) + 1];
|
|
m_prs->StripBrackets(lpszName, lpszNoBracketName);
|
|
|
|
// Finish setting up column binding info struct
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&m_prs->m_prgDaoColBindInfo[m_nField-1];
|
|
pcb->cbInfoOffset =
|
|
(DWORD)&m_prs->m_pulColumnLengths[m_nField-1];
|
|
#ifndef _UNICODE
|
|
pcb->columnID.dwKind = DAOCOLKIND_STR;
|
|
pcb->columnID.lpstr = lpszNoBracketName;
|
|
#else
|
|
pcb->columnID.dwKind = DAOCOLKIND_WSTR;
|
|
pcb->columnID.lpwstr = lpszNoBracketName;
|
|
#endif
|
|
|
|
// Setup the field index map (and store value as void ptr)
|
|
m_prs->m_pMapFieldIndex->SetAt(pv, (void*)m_nField);
|
|
}
|
|
return;
|
|
|
|
case BindParam:
|
|
{
|
|
COleVariant* pvar = NULL;
|
|
|
|
TRY
|
|
{
|
|
// NULL params not supported, use IS NULL in SQL
|
|
// (i.e. - m_strFilter = _T("Foo IS NULL");
|
|
FillVariant(pv, dwColumnType, &pvar);
|
|
m_prs->m_pQueryDef->SetParamValue(lpszName, *pvar);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pvar != NULL)
|
|
pvar->Clear();
|
|
delete pvar;
|
|
pvar = NULL;
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pvar->Clear();
|
|
delete pvar;
|
|
pvar = NULL;
|
|
}
|
|
return;
|
|
|
|
case Fixup:
|
|
if (m_prs->GetFieldLength(m_nField-1) == DAO_NULL)
|
|
{
|
|
// Set the value to PSEUDO NULL and mark the status NULL
|
|
SetNullValue(pv, dwColumnType);
|
|
m_prs->SetNullFieldStatus(m_nField-1);
|
|
}
|
|
return;
|
|
|
|
case AllocCache:
|
|
if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
|
|
{
|
|
CDaoFieldCache* pCache;
|
|
|
|
// Allocate new storage and add to map
|
|
AllocCacheValue(pCache, dwColumnType);
|
|
m_prs->m_pMapFieldCache->SetAt(pv, pCache);
|
|
}
|
|
return;
|
|
|
|
case StoreField:
|
|
if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
|
|
{
|
|
CDaoFieldCache* pCache = GetCacheValue(m_prs, pv);
|
|
|
|
// Copy the data to the cache
|
|
CopyValue(pv, pCache->m_pvData, dwColumnType);
|
|
|
|
// Cache the NULL status
|
|
if (m_prs->IsFieldStatusNull(m_nField-1))
|
|
pCache->m_nStatus |= AFX_DAO_FIELD_FLAG_NULL;
|
|
else
|
|
pCache->m_nStatus &= ~AFX_DAO_FIELD_FLAG_NULL;
|
|
}
|
|
return;
|
|
|
|
case LoadField:
|
|
if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
|
|
{
|
|
CDaoFieldCache* pCache = GetCacheValue(m_prs, pv);
|
|
|
|
// Copy the data from the cache
|
|
CopyValue(pCache->m_pvData, pv, dwColumnType);
|
|
|
|
// Set the NULL status from the cache
|
|
if (pCache->m_nStatus & AFX_DAO_FIELD_FLAG_NULL)
|
|
m_prs->SetNullFieldStatus(m_nField-1);
|
|
else
|
|
m_prs->ClearNullFieldStatus(m_nField-1);
|
|
}
|
|
return;
|
|
|
|
case SetFieldNull:
|
|
// Setting field NOT NULL doesn't require field exchange
|
|
if ((m_pvField == NULL && m_nFieldType == outputColumn)
|
|
|| m_pvField == pv)
|
|
{
|
|
SetNullValue(pv, dwColumnType);
|
|
|
|
// Also set the status array if not a parameter
|
|
if (m_nFieldType == outputColumn)
|
|
m_prs->SetNullFieldStatus(m_nField-1);
|
|
|
|
#ifdef _DEBUG
|
|
m_nFieldFound = m_nField;
|
|
#endif
|
|
}
|
|
return;
|
|
|
|
case MarkForAddNew:
|
|
if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
|
|
{
|
|
// Don't need to do anything if field marked dirty
|
|
if (!m_prs->IsFieldStatusDirty(m_nField-1))
|
|
{
|
|
// Mark dirty & not NULL if not set to pseudo NULL value
|
|
if (!IsNullValue(pv, dwColumnType))
|
|
{
|
|
m_prs->SetDirtyFieldStatus(m_nField-1);
|
|
m_prs->ClearNullFieldStatus(m_nField-1);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
|
|
case MarkForEdit:
|
|
if (dwBindOptions & AFX_DAO_ENABLE_FIELD_CACHE)
|
|
{
|
|
// If value not pseudo NULL value, clear NULL status
|
|
if (!IsNullValue(pv, dwColumnType))
|
|
m_prs->ClearNullFieldStatus(m_nField-1);
|
|
|
|
// If field already marked dirty, don't need to check cache
|
|
if (!m_prs->IsFieldStatusDirty(m_nField-1))
|
|
{
|
|
CDaoFieldCache* pCache = GetCacheValue(m_prs, pv);
|
|
|
|
BOOL bNullField = m_prs->IsFieldStatusNull(m_nField-1);
|
|
BOOL bNullCache = pCache->m_nStatus & AFX_DAO_FIELD_FLAG_NULL;
|
|
|
|
// Mark dirty if NULL status differs or value differs
|
|
if ( (bNullCache && !bNullField) ||
|
|
(!bNullCache && bNullField) ||
|
|
CompareValue(pv, pCache->m_pvData, dwColumnType))
|
|
{
|
|
m_prs->SetDirtyFieldStatus(m_nField-1);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
|
|
case SetDirtyField:
|
|
if (m_prs->IsFieldStatusDirty(m_nField-1))
|
|
{
|
|
COleVariant* pvar = NULL;
|
|
|
|
TRY
|
|
{
|
|
// If field is NULL don't set the value
|
|
if (!m_prs->IsFieldStatusNull(m_nField-1))
|
|
FillVariant(pv, dwColumnType, &pvar);
|
|
else
|
|
{
|
|
pvar = new COleVariant;
|
|
pvar->vt = VT_NULL;
|
|
}
|
|
|
|
// SetFieldValue (put_Collect) doesn't like brackets
|
|
// Assumes no brackets if first char not a bracket
|
|
LPTSTR lpszModifiedName = NULL;
|
|
if (*lpszName == '[')
|
|
{
|
|
lpszModifiedName = new TCHAR[_tcslen(lpszName) + 1];
|
|
|
|
// Copy the name with no brackets, and reset lpszName
|
|
m_prs->StripBrackets(lpszName, lpszModifiedName);
|
|
lpszName = lpszModifiedName;
|
|
}
|
|
|
|
m_prs->SetFieldValue(lpszName, *pvar);
|
|
delete lpszModifiedName;
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pvar != NULL)
|
|
pvar->Clear();
|
|
delete pvar;
|
|
pvar = NULL;
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pvar->Clear();
|
|
delete pvar;
|
|
pvar = NULL;
|
|
}
|
|
return;
|
|
|
|
default:
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Text(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
CString& value, int nPreAllocSize, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
DWORD dwDAOType;
|
|
|
|
#ifdef _UNICODE
|
|
dwDAOType = DAO_WCHAR;
|
|
#else
|
|
dwDAOType = DAO_CHAR;
|
|
#endif
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
// Pre-allocate buffer to prevent needless re-allocations
|
|
value.GetBuffer(nPreAllocSize);
|
|
value.ReleaseBuffer();
|
|
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = dwDAOType;
|
|
pcb->dwBinding = DAOBINDING_DIRECT | DAOBINDING_CALLBACK;
|
|
pcb->dwUser = (DWORD)&value;
|
|
pcb->cbDataOffset = (DWORD)DaoStringAllocCallback;
|
|
pcb->cbMaxLen = INT_MAX;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_TEXT,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
case CDaoFieldExchange::Fixup:
|
|
if (pFX->m_prs->m_pulColumnLengths[pFX->m_nField-1] == 0 ||
|
|
pFX->m_prs->m_pulColumnLengths[pFX->m_nField-1] == DAO_NULL)
|
|
{
|
|
// If null or empty string set length zero
|
|
value.GetBufferSetLength(0);
|
|
}
|
|
else
|
|
{
|
|
// Make sure length correct (and doesn't include NULL terminator)
|
|
value.GetBufferSetLength(
|
|
pFX->m_prs->m_pulColumnLengths[pFX->m_nField-1] - 1);
|
|
}
|
|
|
|
pFX->Default(lpszName, (void*)&value,
|
|
AFX_RFX_TEXT, dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Binary(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
CByteArray& value, int nPreAllocSize, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
// Pre-allocate buffer to prevent needless re-allocations
|
|
value.SetSize(nPreAllocSize);
|
|
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_BYTES;
|
|
pcb->dwBinding = DAOBINDING_DIRECT | DAOBINDING_CALLBACK;
|
|
pcb->dwUser = (DWORD)&value;
|
|
pcb->cbDataOffset = (ULONG)DaoBinaryAllocCallback;
|
|
pcb->cbMaxLen = INT_MAX;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_BINARY,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_LongBinary(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
CLongBinary& value, DWORD dwPreAllocSize, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
// Pre-allocate buffer to prevent needless re-allocations
|
|
AllocLongBinary(value, dwPreAllocSize);
|
|
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_BYTES;
|
|
pcb->dwBinding = DAOBINDING_DIRECT | DAOBINDING_CALLBACK;
|
|
pcb->dwUser = (DWORD)&value;
|
|
pcb->cbDataOffset = (DWORD)DaoLongBinaryAllocCallback;
|
|
pcb->cbMaxLen = ULONG_MAX;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value,
|
|
AFX_RFX_LONGBINARY, dwBindOptions);
|
|
return;
|
|
|
|
case CDaoFieldExchange::Fixup:
|
|
// Unlock data locked in DaoLongBinaryAllocCallback
|
|
if (value.m_dwDataLength != 0)
|
|
::GlobalUnlock(value.m_hData);
|
|
|
|
pFX->Default(lpszName, (void*)&value,
|
|
AFX_RFX_LONGBINARY, dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Bool(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
BOOL& value, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_BOOL;
|
|
pcb->dwBinding = DAOBINDING_DIRECT;
|
|
pcb->cbDataOffset = (DWORD)&value;
|
|
pcb->dwUser = 0;
|
|
pcb->cbMaxLen = sizeof(value);
|
|
|
|
pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_BOOL,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
case CDaoFieldExchange::Fixup:
|
|
// Convert BOOL value from AFX_DAO_TRUE/FALSE to TRUE/FALSE
|
|
value = (value != AFX_DAO_FALSE);
|
|
|
|
pFX->Default(lpszName, (void*)&value,
|
|
AFX_RFX_LONGBINARY, dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Byte(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
BYTE& value, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_BYTE;
|
|
pcb->dwBinding = DAOBINDING_DIRECT;
|
|
pcb->cbDataOffset = (DWORD)&value;
|
|
pcb->dwUser = 0;
|
|
pcb->cbMaxLen = sizeof(value);
|
|
|
|
pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_BYTE,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Short(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
short& value, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_I2;
|
|
pcb->dwBinding = DAOBINDING_DIRECT;
|
|
pcb->cbDataOffset = (DWORD)&value;
|
|
pcb->dwUser = 0;
|
|
pcb->cbMaxLen = sizeof(value);
|
|
|
|
pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_SHORT,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Long(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
long& value, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_I4;
|
|
pcb->dwBinding = DAOBINDING_DIRECT;
|
|
pcb->cbDataOffset = (DWORD)&value;
|
|
pcb->dwUser = 0;
|
|
pcb->cbMaxLen = sizeof(value);
|
|
|
|
pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_LONG,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Currency(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
COleCurrency& value, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_CURRENCY;
|
|
pcb->dwBinding = DAOBINDING_DIRECT;
|
|
pcb->cbDataOffset = (DWORD)&value.m_cur;
|
|
pcb->dwUser = 0;
|
|
pcb->cbMaxLen = sizeof(CURRENCY);
|
|
|
|
pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
|
|
|
|
// Finish setting up column binding struct
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_CURRENCY,
|
|
dwBindOptions);
|
|
return;
|
|
}
|
|
|
|
case CDaoFieldExchange::Fixup:
|
|
// Must reset the valid currency flag
|
|
if (pFX->m_prs->GetFieldLength(pFX->m_nField-1) == DAO_NULL)
|
|
value.SetStatus(COleCurrency::null);
|
|
else
|
|
value.SetStatus(COleCurrency::valid);
|
|
|
|
// Fall through to reset the NULL status
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_CURRENCY,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << ":" << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Single(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
float& value, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_R4;
|
|
pcb->dwBinding = DAOBINDING_DIRECT;
|
|
pcb->cbDataOffset = (DWORD)&value;
|
|
pcb->dwUser = 0;
|
|
pcb->cbMaxLen = sizeof(value);
|
|
|
|
pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_SINGLE,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_Double(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
double& value, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_R8;
|
|
pcb->dwBinding = DAOBINDING_DIRECT;
|
|
pcb->cbDataOffset = (DWORD)&value;
|
|
pcb->dwUser = 0;
|
|
pcb->cbMaxLen = sizeof(value);
|
|
|
|
pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
|
|
}
|
|
// Fall through to finish setting up column binding struct
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_DOUBLE,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << " = " << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
void AFXAPI DFX_DateTime(CDaoFieldExchange* pFX, LPCTSTR lpszName,
|
|
COleDateTime& value, DWORD dwBindOptions)
|
|
{
|
|
(pFX->m_nFieldType == CDaoFieldExchange::outputColumn) ?
|
|
++pFX->m_nField: ++pFX->m_nParam;
|
|
|
|
// Do nothing if op not supported for outputColumn or param type
|
|
if (!pFX->IsValidOperation())
|
|
return;
|
|
|
|
switch (pFX->m_nOperation)
|
|
{
|
|
case CDaoFieldExchange::BindField:
|
|
{
|
|
LPDAOCOLUMNBINDING pcb =
|
|
&pFX->m_prs->m_prgDaoColBindInfo[pFX->m_nField-1];
|
|
pcb->dwDataType = DAO_DATE;
|
|
pcb->dwBinding = DAOBINDING_DIRECT;
|
|
pcb->cbDataOffset = (DWORD)&value.m_dt;
|
|
pcb->dwUser = 0;
|
|
pcb->cbMaxLen = sizeof(DATE);
|
|
|
|
pFX->m_prs->m_cbFixedLengthFields += pcb->cbMaxLen;
|
|
|
|
// Finish setting up column binding struct
|
|
pFX->Default(lpszName,(void*)&value, AFX_RFX_DATE,
|
|
dwBindOptions);
|
|
return;
|
|
}
|
|
|
|
case CDaoFieldExchange::Fixup:
|
|
// Must reset the valid currency flag
|
|
if (pFX->m_prs->GetFieldLength(pFX->m_nField-1) == DAO_NULL)
|
|
value.SetStatus(COleDateTime::null);
|
|
else
|
|
value.SetStatus(COleDateTime::valid);
|
|
|
|
// Fall through to reset the NULL status
|
|
|
|
default:
|
|
pFX->Default(lpszName, (void*)&value, AFX_RFX_DATE,
|
|
dwBindOptions);
|
|
return;
|
|
|
|
#ifdef _DEBUG
|
|
case CDaoFieldExchange::DumpField:
|
|
*pFX->m_pdcDump << "\n" << lpszName << ":" << value;
|
|
return;
|
|
#endif //_DEBUG
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// DAO memory allocation callback helpers
|
|
|
|
STDAPI DaoStringAllocCallback(DWORD dwLen, DWORD pData, void** ppv)
|
|
{
|
|
LPTSTR lpsz;
|
|
CString* pstr = (CString*)pData;
|
|
|
|
#ifndef _UNICODE
|
|
// If using ANSI DAO interfaces, DAO reports field length
|
|
// rather than data length. In this case there will not be space
|
|
// for NULL terminator if data length equals field length. Make room.
|
|
dwLen++;
|
|
#endif
|
|
|
|
TRY
|
|
{
|
|
// Only re-allocate if necessary
|
|
lpsz = pstr->GetBuffer(dwLen);
|
|
pstr->ReleaseBuffer(dwLen);
|
|
*ppv = (void*)(dwLen > 0 ? lpsz : NULL);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
e->Delete();
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDAPI DaoBinaryAllocCallback(DWORD dwLen, DWORD pData, void** ppv)
|
|
{
|
|
CByteArray* pByteArray = (CByteArray*)pData;
|
|
|
|
TRY
|
|
{
|
|
// Only re-allocate if necessary
|
|
pByteArray->SetSize(dwLen);
|
|
*ppv = (void*)(dwLen > 0 ? &((*pByteArray)[0]) : NULL);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Only exceptions thrown should be CMemoryException
|
|
e->Delete();
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDAPI DaoLongBinaryAllocCallback(DWORD dwLen, DWORD pData, void** ppv)
|
|
{
|
|
CLongBinary* pLongBinary = (CLongBinary*)pData;
|
|
|
|
TRY
|
|
{
|
|
AllocLongBinary(*pLongBinary, dwLen);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Only exception is memory exception, just pass back error.
|
|
DELETE_EXCEPTION(e);
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
if (pLongBinary->m_dwDataLength != 0)
|
|
{
|
|
const BYTE* pByte;
|
|
pByte = (const BYTE*)::GlobalLock(pLongBinary->m_hData);
|
|
|
|
// If mem can't be locked, free up and return error
|
|
if (pByte == NULL)
|
|
{
|
|
::GlobalFree(pLongBinary->m_hData);
|
|
pLongBinary->m_hData = NULL;
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
*ppv = (void*)pByte;
|
|
}
|
|
else
|
|
*ppv = NULL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
void AFX_CDECL AllocLongBinary(CLongBinary& lb, DWORD dwDataLength)
|
|
{
|
|
if (lb.m_hData == NULL)
|
|
{
|
|
if (dwDataLength > 0)
|
|
{
|
|
// Alloc memory, return error if not possible
|
|
lb.m_hData = ::GlobalAlloc(GMEM_MOVEABLE, dwDataLength);
|
|
if (lb.m_hData == NULL)
|
|
AfxThrowMemoryException();
|
|
}
|
|
}
|
|
else if (::GlobalSize(lb.m_hData) < dwDataLength)
|
|
{
|
|
// Alloc more mem, free up mem and throw exception if not possible
|
|
if (::GlobalReAlloc(lb.m_hData, dwDataLength, 0) == NULL)
|
|
{
|
|
::GlobalFree(lb.m_hData);
|
|
AfxThrowMemoryException();
|
|
}
|
|
}
|
|
lb.m_dwDataLength = dwDataLength;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Inline function declarations expanded out-of-line
|
|
|
|
#ifndef _AFX_ENABLE_INLINES
|
|
|
|
static char _szAfxDaoInl[] = "afxdao.inl";
|
|
#undef THIS_FILE
|
|
#define THIS_FILE _szAfxDaoInl
|
|
#define _AFXDAODFX_INLINE
|
|
#include "afxdao.inl"
|
|
|
|
#endif
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|