home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
mfc
/
src
/
dbflt.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-16
|
9KB
|
339 lines
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 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 <float.h>
#ifdef AFX_DB_SEG
#pragma code_seg(AFX_DB_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Helpers for floating point operations
const float afxFloatPseudoNull = AFX_RFX_SINGLE_PSEUDO_NULL;
const double afxDoublePseudoNull = AFX_RFX_DOUBLE_PSEUDO_NULL;
extern void AFXAPI AfxTextFloatFormat(CDataExchange* pDX, int nIDC,
void* pData, double value, int nSizeGcvt);
extern BOOL AFXAPI AfxFieldText(CDataExchange* pDX, int nIDC, void* pv,
CRecordset* pRecordset);
void AFXAPI RFX_Single(CFieldExchange* pFX, LPCTSTR szName,
float& value)
{
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
ASSERT(AfxIsValidString(szName));
UINT nField;
if (!pFX->IsFieldType(&nField))
return;
LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(nField - 1, pFX->m_nFieldType);
switch (pFX->m_nOperation)
{
case CFieldExchange::BindFieldToColumn:
{
#ifdef _DEBUG
// Assumes all bound fields BEFORE unbound fields
CODBCFieldInfo* pODBCInfo =
&pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
if (pODBCInfo->m_nSQLType != SQL_C_FLOAT)
{
// Warn of possible field schema mismatch
if (afxTraceFlags & traceDatabase)
TRACE1("Warning: float converted from SQL type %ld.\n",
pODBCInfo->m_nSQLType);
}
#endif
}
// fall through
default:
LDefault:
pFX->Default(szName, &value, plLength, SQL_C_FLOAT,
sizeof(value), 13);
return;
case CFieldExchange::Fixup:
if (*plLength == SQL_NULL_DATA)
{
pFX->m_prs->SetNullFieldStatus(nField - 1);
value = afxFloatPseudoNull;
}
return;
case CFieldExchange::SetFieldNull:
if ((pFX->m_pvField == NULL &&
pFX->m_nFieldType == CFieldExchange::outputColumn) ||
pFX->m_pvField == &value)
{
if (pFX->m_bField)
{
pFX->m_prs->SetNullFieldStatus(nField - 1);
value = afxFloatPseudoNull;
*plLength = SQL_NULL_DATA;
}
else
{
pFX->m_prs->ClearNullFieldStatus(nField - 1);
*plLength = sizeof(value);
}
#ifdef _DEBUG
pFX->m_nFieldFound = nField;
#endif
}
return;
case CFieldExchange::MarkForAddNew:
// can force writing of psuedo-null value (as a non-null) by setting field dirty
if (value != afxFloatPseudoNull)
{
pFX->m_prs->SetDirtyFieldStatus(nField - 1);
pFX->m_prs->ClearNullFieldStatus(nField - 1);
}
return;
case CFieldExchange::MarkForUpdate:
if (value != afxFloatPseudoNull)
pFX->m_prs->ClearNullFieldStatus(nField - 1);
goto LDefault;
case CFieldExchange::AllocCache:
{
CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
// Data cached by value, no allocation necessary
pInfo->m_nDataType = AFX_RFX_SINGLE;
}
return;
#ifdef _DEBUG
case CFieldExchange::DumpField:
{
*pFX->m_pdcDump << "\n" << szName << " = " << value;
}
return;
#endif //_DEBUG
}
}
void AFXAPI RFX_Double(CFieldExchange* pFX, LPCTSTR szName,
double& value)
{
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
ASSERT(AfxIsValidString(szName));
UINT nField;
if (!pFX->IsFieldType(&nField))
return;
LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(nField - 1, pFX->m_nFieldType);
switch (pFX->m_nOperation)
{
case CFieldExchange::BindFieldToColumn:
{
#ifdef _DEBUG
// Assumes all bound fields BEFORE unbound fields
CODBCFieldInfo* pODBCInfo =
&pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
if (pODBCInfo->m_nSQLType != SQL_C_DOUBLE &&
pODBCInfo->m_nSQLType != SQL_FLOAT)
{
// Warn of possible field schema mismatch
if (afxTraceFlags & traceDatabase)
TRACE1("Warning: double converted from SQL type %ld.\n",
pODBCInfo->m_nSQLType);
}
#endif
}
// fall through
default:
LDefault:
pFX->Default(szName, &value, plLength, SQL_C_DOUBLE,
sizeof(value), 22);
return;
case CFieldExchange::Fixup:
if (*plLength == SQL_NULL_DATA)
{
pFX->m_prs->SetNullFieldStatus(nField - 1);
value = afxDoublePseudoNull;
}
return;
case CFieldExchange::SetFieldNull:
if ((pFX->m_pvField == NULL &&
pFX->m_nFieldType == CFieldExchange::outputColumn) ||
pFX->m_pvField == &value)
{
if (pFX->m_bField)
{
pFX->m_prs->SetNullFieldStatus(nField - 1);
value = afxDoublePseudoNull;
*plLength = SQL_NULL_DATA;
}
else
{
pFX->m_prs->ClearNullFieldStatus(nField - 1);
*plLength = sizeof(value);
}
#ifdef _DEBUG
pFX->m_nFieldFound = nField;
#endif
}
return;
case CFieldExchange::MarkForAddNew:
// can force writing of psuedo-null value (as a non-null) by setting field dirty
if (value != afxDoublePseudoNull)
{
pFX->m_prs->SetDirtyFieldStatus(nField - 1);
pFX->m_prs->ClearNullFieldStatus(nField - 1);
}
return;
case CFieldExchange::MarkForUpdate:
if (value != afxDoublePseudoNull)
pFX->m_prs->ClearNullFieldStatus(nField - 1);
goto LDefault;
case CFieldExchange::AllocCache:
{
CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
pInfo->m_pvDataCache = new double;
pInfo->m_nDataType = AFX_RFX_DOUBLE;
}
return;
#ifdef _DEBUG
case CFieldExchange::DumpField:
{
*pFX->m_pdcDump << "\n" << szName << " = " << value;
}
return;
#endif //_DEBUG
}
}
/////////////////////////////////////////////////////////////////////////////
void AFXAPI RFX_Single_Bulk(CFieldExchange* pFX, LPCTSTR szName,
float** prgFltVals, long** prgLengths)
{
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
ASSERT(AfxIsValidString(szName));
UINT nField;
if (!pFX->IsFieldType(&nField))
return;
switch (pFX->m_nOperation)
{
case CFieldExchange::AllocMultiRowBuffer:
{
// The buffer pointer better be initialized to NULL
// or cleanup in exceptional cases mail fail
ASSERT(*prgFltVals == NULL);
ASSERT(*prgLengths == NULL);
int nRowsetSize = pFX->m_prs->GetRowsetSize();
// Allocate buffers to hold data and length
*prgFltVals = new float[nRowsetSize];
*prgLengths = new long[nRowsetSize];
}
break;
case CFieldExchange::DeleteMultiRowBuffer:
delete [] *prgFltVals;
*prgFltVals = NULL;
delete [] *prgLengths;
*prgLengths = NULL;
break;
default:
AfxRFXBulkDefault(pFX, szName, *prgFltVals, *prgLengths,
SQL_C_FLOAT, sizeof(float));
break;
}
}
void AFXAPI RFX_Double_Bulk(CFieldExchange* pFX, LPCTSTR szName,
double** prgDblVals, long** prgLengths)
{
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
ASSERT(AfxIsValidString(szName));
UINT nField;
if (!pFX->IsFieldType(&nField))
return;
switch (pFX->m_nOperation)
{
case CFieldExchange::AllocMultiRowBuffer:
{
// The buffer pointer better be initialized to NULL
// or cleanup in exceptional cases mail fail
ASSERT(*prgDblVals == NULL);
ASSERT(*prgLengths == NULL);
int nRowsetSize = pFX->m_prs->GetRowsetSize();
// Allocate buffers to hold data and length
*prgDblVals = new double[nRowsetSize];
*prgLengths = new long[nRowsetSize];
}
break;
case CFieldExchange::DeleteMultiRowBuffer:
delete [] *prgDblVals;
*prgDblVals = NULL;
delete [] *prgLengths;
*prgLengths = NULL;
break;
default:
AfxRFXBulkDefault(pFX, szName, *prgDblVals, *prgLengths,
SQL_C_DOUBLE, sizeof(double));
break;
}
}
/////////////////////////////////////////////////////////////////////////////
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, float& value,
CRecordset* pRecordset)
{
if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
AfxTextFloatFormat(pDX, nIDC, &value, value, FLT_DIG);
}
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, double& value,
CRecordset* pRecordset)
{
if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
AfxTextFloatFormat(pDX, nIDC, &value, value, DBL_DIG);
}
/////////////////////////////////////////////////////////////////////////////