📄 coledb.cpp
字号:
::CoTaskMemFree(rgColumnInfo);
// Create accessor
CComQIPtr<IAccessor> spAccessor = m_spRowset;
if( spAccessor == NULL ) return FALSE;
Hr = spAccessor->CreateAccessor(DBACCESSOR_ROWDATA, m_nCols, m_rgBindings, 0, &m_hAccessor, NULL);
if( FAILED(Hr) ) return _Error(Hr);
m_pData = ::CoTaskMemAlloc(m_dwBufferSize);
if( m_pData == NULL ) return FALSE;
return TRUE;
}
//////////////////////////////////////////////////////////////
// COledbCommand
//
COledbCommand::COledbCommand(COledbDatabase* pDb) :
m_pDb(pDb),
m_rgBindings(NULL),
m_hAccessor(DB_NULL_HACCESSOR),
m_nParams(0),
m_pData(NULL)
{
_ASSERTE(m_pDb);
_ASSERTE(m_pDb->IsOpen());
#ifdef _DEBUG
m_pDb->m_nRecordsets++;
#endif
}
COledbCommand::~COledbCommand()
{
Close();
#ifdef _DEBUG
m_pDb->m_nRecordsets--;
#endif
}
BOOL COledbCommand::Create(LPCTSTR pstrSQL, long lType /*= DB_OPEN_TYPE_FORWARD_ONLY*/, long lOptions /*= DB_OPTION_DEFAULT*/)
{
_ASSERTE(m_pDb->IsOpen());
_ASSERTE(!::IsBadStringPtr(pstrSQL,-1));
HRESULT Hr;
Close();
// Open the command
CComQIPtr<IDBCreateCommand> spCreate = m_pDb->m_spSession;
if( spCreate == NULL ) return FALSE;
CComPtr<ICommand> spCommand;
Hr = spCreate->CreateCommand(NULL, IID_ICommand, (LPUNKNOWN*) &spCommand);
if( FAILED(Hr) ) return _Error(Hr);
COledbDatabase::_SetRecordsetType(spCommand, lType, lOptions);
m_spText = spCommand;
_ASSERTE(m_spText);
USES_CONVERSION;
Hr = m_spText->SetCommandText(DBGUID_DBSQL, T2COLE(pstrSQL));
if( FAILED(Hr) ) return _Error(Hr);
// Prepare the command
if( (lOptions & DB_OPTION_PREPARE) != 0 ) {
CComQIPtr<ICommandPrepare> spPrepare = m_spText;
_ASSERTE(spPrepare);
if( spPrepare ) {
Hr = spPrepare->Prepare(0);
if( FAILED(Hr) ) return _Error(Hr);
}
}
// Create parameter bindings memory area
long cbAlloc = MAX_PARAMS * sizeof(DBBINDING);
m_rgBindings = (DBBINDING*) ::CoTaskMemAlloc(cbAlloc);
if( m_rgBindings == NULL ) return FALSE;
::ZeroMemory(m_rgBindings, cbAlloc);
m_pData = ::CoTaskMemAlloc(MAX_PARAMBUFFER_SIZE);
_ASSERTE(m_pData);
if( m_pData == NULL ) return FALSE;
::ZeroMemory(m_pData, MAX_PARAMBUFFER_SIZE);
m_nParams = 0;
m_dwBindOffset = 0L;
return TRUE;
}
void COledbCommand::Close()
{
if( m_rgBindings ) {
::CoTaskMemFree(m_rgBindings);
m_rgBindings = NULL;
}
if( m_pData ) {
::CoTaskMemFree(m_pData);
m_pData = NULL;
}
m_hAccessor = DB_NULL_HACCESSOR;
m_spText.Release();
m_spRowset.Release();
m_nParams = 0;
}
BOOL COledbCommand::Cancel()
{
_ASSERTE(IsOpen());
CComQIPtr<ICommand> spCmd = m_spText;
if( spCmd == NULL ) return FALSE;
if( FAILED( spCmd->Cancel() ) ) return FALSE;
return TRUE;
}
BOOL COledbCommand::Execute(CDbRecordset* pRecordset /*= NULL*/)
{
_ASSERTE(m_spText);
HRESULT Hr;
m_nRowsAffected = 0;
// Create accessor
CComQIPtr<IAccessor> spAccessor = m_spText;
if( spAccessor == NULL ) return FALSE;
if( m_nParams > 0 ) {
#ifdef _DEBUG
DBBINDSTATUS stat[MAX_PARAMS] = { 0 };
Hr = spAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA, m_nParams, m_rgBindings, m_dwBindOffset, &m_hAccessor, stat);
#else
Hr = spAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA, m_nParams, m_rgBindings, m_dwBindOffset, &m_hAccessor, NULL);
#endif
if( FAILED(Hr) ) return _Error(Hr);
}
DBPARAMS Params;
Params.pData = m_pData;
Params.cParamSets = m_nParams > 0 ? 1 : 0;
Params.hAccessor = m_hAccessor;
Hr = m_spText->Execute(NULL, IID_IRowset, &Params, &m_nRowsAffected, (LPUNKNOWN*) &m_spRowset);
if( FAILED(Hr) ) return _Error(Hr);
// Did we want to see the result set?
if( m_spRowset != NULL && pRecordset != NULL ) {
COledbRecordset* pRec = static_cast<COledbRecordset*>(pRecordset);
return pRec->Attach(m_spRowset);
}
return TRUE;
}
BOOL COledbCommand::IsOpen() const
{
return m_spRowset != NULL;
}
DWORD COledbCommand::GetRowCount() const
{
return m_nRowsAffected;
}
BOOL COledbCommand::SetParam(short iIndex, const long* pData)
{
_ASSERTE(m_rgBindings);
_ASSERTE(iIndex<MAX_PARAMS);
// Fill out binding info
DBBINDING& b = m_rgBindings[m_nParams];
b.iOrdinal = iIndex + 1;
b.wType = DBTYPE_I4;
b.cbMaxLen = sizeof(long);
b.dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
b.obStatus = m_dwBindOffset;
b.obLength = m_dwBindOffset + sizeof(DBSTATUS);
b.obValue = m_dwBindOffset + sizeof(DBSTATUS) + sizeof(ULONG);
b.dwMemOwner = DBMEMOWNER_CLIENTOWNED;
b.eParamIO = DBPARAMIO_INPUT;
b.bPrecision = 0;
b.bScale = 0;
// Set value
* (long*) ( (LPBYTE) m_pData + b.obValue ) = *pData;
// Update the offset past the end of this column's data
m_dwBindOffset = b.cbMaxLen + b.obValue;
m_dwBindOffset = ROUNDUP(m_dwBindOffset);
_ASSERTE(m_dwBindOffset<MAX_PARAMBUFFER_SIZE);
// Manage parameter count
if( iIndex >= m_nParams ) m_nParams = (short) (iIndex + 1);
return TRUE;
}
BOOL COledbCommand::SetParam(short iIndex, LPCTSTR pData, UINT cchMax /*= -1*/)
{
_ASSERTE(m_rgBindings);
_ASSERTE(iIndex<MAX_PARAMS);
int nChars = cchMax == -1 ? ::lstrlen(pData) + 1 : cchMax;
int nBytes = nChars * sizeof(TCHAR);
// Fill out binding info
DBBINDING& b = m_rgBindings[m_nParams];
b.iOrdinal = iIndex + 1;
#ifdef _UNICODE
b.wType = DBTYPE_WSTR;
#else
b.wType = DBTYPE_STR;
#endif
b.cbMaxLen = nBytes;
b.dwPart = DBPART_VALUE;
b.obValue = m_dwBindOffset;
b.dwMemOwner = DBMEMOWNER_CLIENTOWNED;
b.eParamIO = DBPARAMIO_INPUT;
b.bPrecision = 0;
b.bScale = 0;
// Set value
LPTSTR pstr = (LPTSTR) ( (LPBYTE) m_pData + b.obValue );
::lstrcpy( pstr, pData );
// Update the offset past the end of this column's data
m_dwBindOffset = b.cbMaxLen + b.obValue;
m_dwBindOffset = ROUNDUP(m_dwBindOffset);
_ASSERTE(m_dwBindOffset<MAX_PARAMBUFFER_SIZE);
// Manage parameter count
if( iIndex >= m_nParams ) m_nParams = (short) (iIndex + 1);
return TRUE;
}
BOOL COledbCommand::SetParam(short /*iIndex*/, const bool* /*pData*/)
{
_ASSERTE(m_rgBindings);
_ASSERTE(false);
return FALSE;
}
BOOL COledbCommand::SetParam(short iIndex, const float* pData)
{
_ASSERTE(m_rgBindings);
_ASSERTE(iIndex<MAX_PARAMS);
// Fill out binding info
DBBINDING& b = m_rgBindings[m_nParams];
b.iOrdinal = iIndex + 1;
b.wType = DBTYPE_R4;
b.cbMaxLen = sizeof(float);
b.dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
b.obStatus = m_dwBindOffset;
b.obLength = m_dwBindOffset + sizeof(DBSTATUS);
b.obValue = m_dwBindOffset + sizeof(DBSTATUS) + sizeof(ULONG);
b.dwMemOwner = DBMEMOWNER_CLIENTOWNED;
b.eParamIO = DBPARAMIO_INPUT;
b.bPrecision = 0;
b.bScale = 0;
// Set value
* (float*) ( (LPBYTE)m_pData + b.obValue ) = *pData;
// Update the offset past the end of this column's data
m_dwBindOffset = b.cbMaxLen + b.obValue;
m_dwBindOffset = ROUNDUP(m_dwBindOffset);
_ASSERTE(m_dwBindOffset<MAX_PARAMBUFFER_SIZE);
// Manage parameter count
if( iIndex >= m_nParams ) m_nParams = (short) (iIndex + 1);
return TRUE;
}
BOOL COledbCommand::SetParam(short iIndex, const double* pData)
{
_ASSERTE(m_rgBindings);
_ASSERTE(iIndex<MAX_PARAMS);
// Fill out binding info
DBBINDING& b = m_rgBindings[m_nParams];
b.iOrdinal = iIndex + 1;
b.wType = DBTYPE_R8;
b.cbMaxLen = sizeof(double);
b.dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
b.obStatus = m_dwBindOffset;
b.obLength = m_dwBindOffset + sizeof(DBSTATUS);
b.obValue = m_dwBindOffset + sizeof(DBSTATUS) + sizeof(ULONG);
b.dwMemOwner = DBMEMOWNER_CLIENTOWNED;
b.eParamIO = DBPARAMIO_INPUT;
b.bPrecision = 0;
b.bScale = 0;
// Set value
* (double*) ( (LPBYTE)m_pData + b.obValue ) = *pData;
// Update the offset past the end of this column's data
m_dwBindOffset = b.cbMaxLen + b.obValue;
m_dwBindOffset = ROUNDUP(m_dwBindOffset);
_ASSERTE(m_dwBindOffset<MAX_PARAMBUFFER_SIZE);
// Manage parameter count
if( iIndex >= m_nParams ) m_nParams = (short) (iIndex + 1);
return TRUE;
}
BOOL COledbCommand::SetParam(short /*iIndex*/, const SYSTEMTIME* /*pData*/, short /*iType*/)
{
_ASSERTE(m_rgBindings);
// TODO: Code here...
_ASSERTE(false);
return FALSE;
}
#if defined(_STRING_)
BOOL COledbCommand::SetParam(short iIndex, std::string& str)
{
return SetParam(iIndex, str.c_str());
}
#endif // _STRING
#if defined(__ATLSTR_H__) || defined(_WTL_USE_CSTRING)
BOOL COledbCommand::SetParam(short iIndex, CString& str)
{
return SetParam(iIndex, (LPCTSTR) str);
}
#endif // __ATLSTR_H__
BOOL COledbCommand::_Error(HRESULT Hr)
{
_ASSERTE(m_pDb);
return m_pDb->_Error(Hr);
}
//////////////////////////////////////////////////////////////
// COledbErrors
//
COledbErrors::COledbErrors()
: m_lCount(0L)
{
}
COledbErrors::~COledbErrors()
{
}
void COledbErrors::_Init(HRESULT Hr)
{
m_lCount = 0;
CComPtr<IErrorInfo> spErrorInfo;
::GetErrorInfo(0, &spErrorInfo);
if( spErrorInfo == NULL ) {
// No error object
m_p[0]._Init(Hr, CComBSTR(L"System"), CComBSTR(L"Function failed."));
m_lCount = 1;
return;
}
CComQIPtr<IErrorRecords> spErrorRecs = spErrorInfo;
if( spErrorRecs != NULL ) {
// Provider supports IErrorRecords
ULONG nCount = 0;
spErrorRecs->GetRecordCount(&nCount);
for( ULONG i = 0; i < nCount; i++ ) {
HRESULT Hr;
ERRORINFO ErrorInfo;
Hr = spErrorRecs->GetBasicErrorInfo(i, &ErrorInfo);
if( FAILED(Hr) ) break;
CComPtr<IErrorInfo> spErrorInfoRec;
Hr = spErrorRecs->GetErrorInfo(i, ::GetUserDefaultLCID(), &spErrorInfoRec);
if( FAILED(Hr) ) break;
CComBSTR bstrSource;
spErrorInfoRec->GetSource(&bstrSource);
CComBSTR bstrMsg;
spErrorInfoRec->GetDescription(&bstrMsg);
m_p[m_lCount]._Init(ErrorInfo.hrError, bstrSource, bstrMsg);
m_lCount++;
if( m_lCount >= MAX_ERRORS ) break;
}
}
if( m_lCount == 0 ) {
// Provider only supports IErrorInfo
CComBSTR bstrSource;
spErrorInfo->GetSource(&bstrSource);
CComBSTR bstrMsg;
spErrorInfo->GetDescription(&bstrMsg);
m_p[m_lCount]._Init(Hr, bstrSource, bstrMsg);
m_lCount++;
}
}
long COledbErrors::GetCount() const
{
return m_lCount;
}
void COledbErrors::Clear()
{
m_lCount = 0;
}
CDbError* COledbErrors::GetError(short iIndex)
{
_ASSERTE(iIndex>=0 && iIndex<m_lCount);
if( iIndex < 0 || iIndex >= m_lCount ) return NULL;
return &m_p[iIndex];
}
//////////////////////////////////////////////////////////////
// COledbError
//
COledbError::COledbError()
{
}
COledbError::~COledbError()
{
}
void COledbError::_Init(long lNativeCode, BSTR bstrSource, BSTR bstrMsg)
{
m_lNative = lNativeCode;
m_bstrSource = bstrSource;
m_bstrMsg = bstrMsg;
}
long COledbError::GetErrorCode()
{
return m_lNative;
}
long COledbError::GetNativeErrorCode()
{
return m_lNative;
}
void COledbError::GetOrigin(LPTSTR pstrStr, UINT cchMax)
{
USES_CONVERSION;
::lstrcpyn(pstrStr, OLE2CT(m_bstrSource), cchMax);
}
void COledbError::GetMessage(LPTSTR pstrStr, UINT cchMax)
{
USES_CONVERSION;
::lstrcpyn(pstrStr, OLE2CT(m_bstrMsg), cchMax);
}
void COledbError::GetSource(LPTSTR pstrStr, UINT cchMax)
{
USES_CONVERSION;
::lstrcpyn(pstrStr, OLE2CT(m_bstrSource), cchMax);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -