⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coledb.cpp

📁 remote debug and compile tools
💻 CPP
📖 第 1 页 / 共 3 页
字号:

   ::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 + -