📄 daodfx.cpp
字号:
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[lstrlen(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
if (dwBindOptions & AFX_DAO_CACHE_BY_VALUE)
CopyValue(pv, (void*)&pCache->m_pvData, dwColumnType);
else
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
if (dwBindOptions & AFX_DAO_CACHE_BY_VALUE)
CopyValue((void*)&pCache->m_pvData, pv, dwColumnType);
else
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;
void* pvData;
if (dwBindOptions & AFX_DAO_CACHE_BY_VALUE)
pvData = &pCache->m_pvData;
else
pvData = pCache->m_pvData;
// Mark dirty if NULL status differs or value differs
if ( (bNullCache && !bNullField) ||
(!bNullCache && bNullField) ||
CompareValue(pv, 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[lstrlen(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
value.GetBufferSetLength(
((pFX->m_prs->m_pulColumnLengths[pFX->m_nField-1])/sizeof(TCHAR))-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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -