ADO 方法访问数据库的封装接口(02)

类别:VC语言 点击:0 评论:0 推荐:

3. DBConnection.h
#pragma once

#include <comutil.h>
#pragma comment(lib,"comsupp.lib")

class CDBConnectionImpl ;
class CDBRecordSet ;

class AFX_EXT_CLASS CDBConnection
{
 friend class CDBRecordSet ;

public:
 CDBConnection(void);
 virtual ~CDBConnection(void);
 
 /*
  * 设置数据库连接参数
  *  参数:
  *  [in] szServerName -> 数据库所在机器的机器名或者IP地址
  *  [in] szBaseName  -> 数据库实例名称
  *  [in] szUser   -> 数据库登陆用户名
  *  [in] szPasswd  -> 登陆密码
  */
 void SetParameters(LPCTSTR szServerName,LPCTSTR szBaseName,LPCTSTR szUser,LPCTSTR szPasswd) ;

 //是否连接已经打开
 BOOL IsOpened(void) ;

 //打开连接
 BOOL Open(void) ;

 //开始事务
 BOOL BeginTrans(void) ;

 //提交事务
 BOOL CommitTrans(void) ;

 //回滚事务
 BOOL RollbackTrans(void) ;

 /*
  * 执行SQL语句,例如 insert , update 等,不返回记录
  * 参数:
  *  [in] szSQL  -> SQL语句
  *  [out] pnRecordsAffected -> the number of records that the operation affected.
  */
 BOOL Execute(LPCTSTR szSQL,int* pnRecordsAffected = NULL) ;

 /*
  * 执行SQL语句,并返回记录集
  * 参数:
  *  [in] szSQL  -> SQL语句, select ......
  *  [out] recordSet -> 本次查询得到的记录集
  */
 BOOL OpenRecordSet(LPCTSTR szSQL,CDBRecordSet& rRecordSet) ;

 //关闭连接
 BOOL Close(void) ;

 /*
  * 设置错误信息
  *  参数:
  *  [in] szErrMsg  -> 错误信息
  *  [in] szSourceFile -> 发生错误的源文件
  *  [in] nLine   -> 发生错误的行号
  */
 void SetErrorMessage(LPCTSTR szErrMsg,const char* szSourceFile=NULL,int nLine=0);

 //获取错误信息
 LPCTSTR GetErrorMessage(void) const;

 //获取数据库访问的错误信息
 LPCTSTR GetDBConnectionErrorMsg(void) ;
 
public:

 //clone 方法,clone后两个对象具有相同的数据库连接参数,但是各自占有独立的数据库连接,
 //clone 以后,各自有独立的操作,不会相互影响

 BOOL CloneTo(CDBConnection& toConnection) ;


 //copy 后,两个对象使用共同的连接,实际只使用用一个相同的数据库连接
 //对数据库连接的操作会相互影响,需要注意。
 //源的close/open会关闭所有副本的连接,但是副本的close/open不会影响其他连接

 //copy 构造函数
 CDBConnection(const CDBConnection& rConnection) ;

 //赋值运算符
 CDBConnection& operator= (const CDBConnection& rConnection);

protected:

 //生成数据库连接字符串
 void FormatDataSource(void) ;

 //获取数据库连接接口
 BOOL GetConnectionIDispatch(_variant_t& vActiveConnection) ;

protected:

 //数据库连接
 CDBConnectionImpl* m_pConnImpl ;

 //数据库所在机器的机器名或者IP地址
 CString m_strServerName ;

 //数据库实例名称
 CString m_strBaseName ;
 
 //数据库登陆用户名
 CString m_strDBUser ;

 //登陆密码
 CString m_strPasswd ;

 //数据库连接字符串
 CString m_strDataSource ;

 //数据库连接错误
 CString m_strConnErrorMsg ;

};
4. DBConnection.cpp
#include "StdAfx.h"
#include ".\dbconnection.h"
#include "DBConnectionImpl.h"
#include "DBErrorMsgDefs.h"
#include "DBRecordSet.h"

//ADO _ConnectionPtr
#define  DBCONNECTIONPtr m_pConnImpl->GetConnection()

CDBConnection::CDBConnection(void) 
{
 m_pConnImpl = new CDBConnectionImpl() ; 
}

CDBConnection::~CDBConnection(void)
{
 if (m_pConnImpl != NULL)
 {
  delete m_pConnImpl ;
  m_pConnImpl = NULL ;
 }
}

//copy 构造函数
CDBConnection::CDBConnection(const CDBConnection& rConnection):
 m_pConnImpl(NULL)
{
 //调用默认构造函数
 *this = rConnection ;
}

//赋值运算符
CDBConnection& CDBConnection::operator= (const CDBConnection& rConnection)
{
 if(this == &rConnection)
 {
  return *this ;
 }
 m_strServerName = rConnection.m_strServerName ;
 m_strBaseName = rConnection.m_strBaseName ;
 m_strDBUser = rConnection.m_strDBUser ;
 m_strPasswd = rConnection.m_strPasswd ;
 m_strDataSource = rConnection.m_strDataSource ;

 if(rConnection.m_pConnImpl == NULL)
 {
  if(m_pConnImpl != NULL)
  {
   delete m_pConnImpl ;
   m_pConnImpl = NULL ;
  }
 }
 else
 {
  if(m_pConnImpl == NULL)
  {
   m_pConnImpl = new CDBConnectionImpl() ;
  }
  *m_pConnImpl = *rConnection.m_pConnImpl ; //copy it
 }
 return *this ;
}

void CDBConnection::SetParameters(LPCTSTR szServerName,LPCTSTR szBaseName,LPCTSTR szUser,LPCTSTR szPasswd)
{
 m_strServerName = _T("") ;
 m_strBaseName = _T("");
 m_strDBUser = _T("");
 m_strPasswd = _T("") ;
 if(szServerName)
 {
  m_strServerName = szServerName ;
 }

 if (szBaseName)
 {
  m_strBaseName = szBaseName ;
 }

 if(szUser)
 {
  m_strDBUser = szUser ;
 }

 if(szPasswd)
 {
  m_strPasswd = szPasswd ;
 }
 FormatDataSource() ;
}

void CDBConnection::FormatDataSource(void)
{
 m_strDataSource.Format(_T("Provider='sqloledb';Data Source='%s';Initial Catalog='%s';User Id='%s';Password='%s';"),
       (LPCTSTR)m_strServerName,
       (LPCTSTR)m_strBaseName,
       (LPCTSTR)m_strDBUser,
       (LPCTSTR)m_strPasswd
       ) ;
}

//是否连接已经打开
BOOL CDBConnection::IsOpened(void)
{
 if (!m_pConnImpl->isValid())
 {
  SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
  return FALSE ;
 }
 return (DBCONNECTIONPtr->GetState() == adStateOpen);
}

//打开连接
BOOL CDBConnection::Open(void)
{
 try
 {
  if (!m_pConnImpl->isValid())
  {
   SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
   return FALSE ;
  }

  if (m_pConnImpl != NULL)
  {
   if(!m_pConnImpl->GetAutoClose())
   {
    //删除从其他对象复制的连接,防止连接冲突
    delete m_pConnImpl ;
    m_pConnImpl = new CDBConnectionImpl() ;
   }
  }

  //check if is already opened
  if(DBCONNECTIONPtr->GetState() != adStateClosed)
  {
   //if is opened,close it first
   DBCONNECTIONPtr->Close() ;
  }

  DBCONNECTIONPtr->Errors->Clear();
  DBCONNECTIONPtr->CursorLocation = adUseClient;
  DBCONNECTIONPtr->Open(_bstr_t((LPCTSTR)m_strDataSource),_bstr_t(_T("")),_bstr_t(_T("")),adConnectUnspecified);
  return (DBCONNECTIONPtr->GetState() == adStateOpen);
 }
 catch (_com_error &e)
 {
  SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
 }
 catch (...)
 {
  SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
 }
 return FALSE ;
}

//关闭连接
BOOL CDBConnection::Close(void)
{
 try
 {
  if (!m_pConnImpl->isValid())
  {
   SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
   return FALSE ;
  }

  if (m_pConnImpl != NULL)
  {
   if(!m_pConnImpl->GetAutoClose())
   {
    //删除从其他对象复制的连接,防止连接冲突
    delete m_pConnImpl ;
    m_pConnImpl = new CDBConnectionImpl() ;
   }
  }

  HRESULT hr = S_OK ;
  if(DBCONNECTIONPtr->GetState() == adStateOpen)
  {
   hr = DBCONNECTIONPtr->Close() ;
  }
  return (SUCCEEDED(hr)) ;
 }
 catch (_com_error &e)
 {
  SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
 }
 catch (...)
 {
  SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
 }
 return FALSE ;
}

//开始事务
BOOL CDBConnection::BeginTrans(void)
{
 try
 {
  if (!m_pConnImpl->isValid())
  {
   SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
   return FALSE ;
  }
  DBCONNECTIONPtr->Errors->Clear();
  if (DBCONNECTIONPtr->GetState() != adStateClosed)
  {
   DBCONNECTIONPtr->BeginTrans() ;
   return TRUE ;
  }  
 }
 catch (_com_error &e)
 {
  SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
 }
 catch (...)
 {
  SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
 }
 return FALSE ;
}

//提交事务
BOOL CDBConnection::CommitTrans(void)
{
 try
 {
  if (!m_pConnImpl->isValid())
  {
   SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
   return FALSE ;
  }
  DBCONNECTIONPtr->Errors->Clear();
  if (DBCONNECTIONPtr->GetState() != adStateClosed)
  {
   DBCONNECTIONPtr->CommitTrans() ;
   return TRUE ;
  }  
 }
 catch (_com_error &e)
 {
  SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
 }
 catch (...)
 {
  SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
 }
 return FALSE ;
}

//回滚事务
BOOL CDBConnection::RollbackTrans(void)
{
 try
 {
  if (!m_pConnImpl->isValid())
  {
   SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
   return FALSE ;
  }
  DBCONNECTIONPtr->Errors->Clear();
  if (DBCONNECTIONPtr->GetState() != adStateClosed)
  {
   DBCONNECTIONPtr->RollbackTrans() ;
   return TRUE ;
  }  
 }
 catch (_com_error &e)
 {
  SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
 }
 catch (...)
 {
  SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
 }
 return FALSE ;
}

BOOL CDBConnection::Execute(LPCTSTR szSQL,int* pnRecordsAffected)
{
 if(szSQL == NULL)
 {
  SetErrorMessage(SQL_EMPTYSQL,__FILE__,__LINE__) ;
  return FALSE ;
 }
 else if(_tcslen(szSQL) == 0)
 {
  SetErrorMessage(SQL_EMPTYSQL,__FILE__,__LINE__) ;
  return FALSE ;
 }

 try
 {
  if (!m_pConnImpl->isValid())
  {
   SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
   return FALSE ;
  }
  DBCONNECTIONPtr->Errors->Clear();
  if (DBCONNECTIONPtr->GetState() == adStateOpen)
  {
   VARIANT vRecordAffected ;
   VariantInit(&vRecordAffected) ;
   DBCONNECTIONPtr->Execute(_bstr_t(szSQL),&vRecordAffected,adExecuteNoRecords);
   if((VT_I4 == vRecordAffected.vt) && (pnRecordsAffected != NULL))
   {
    *pnRecordsAffected = (int)vRecordAffected.lVal ;
   }
   VariantClear(&vRecordAffected) ;
   return TRUE ;
  }  
 }
 catch (_com_error &e)
 {
  SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
 }
 catch (...)
 {
  SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
 }
 return FALSE ;
}

//获取数据库连接接口
BOOL CDBConnection::GetConnectionIDispatch(_variant_t& vActiveConnection)
{
 if (!m_pConnImpl->isValid())
 {
  SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
  return FALSE ;
 }

 vActiveConnection = (IDispatch*)(DBCONNECTIONPtr);
 return TRUE ;
}

BOOL CDBConnection::OpenRecordSet(LPCTSTR szSQL,CDBRecordSet& rRecordSet)
{
 return rRecordSet.Open(szSQL,*this) ;
}

void CDBConnection::SetErrorMessage(LPCTSTR szErrMsg,const char* szSourceFile,int nLine)
{
 m_pConnImpl->SetErrorMessage(szErrMsg,szSourceFile,nLine) ;
}

LPCTSTR CDBConnection::GetErrorMessage(void) const
{
 return (LPCTSTR)m_pConnImpl->GetErrorMessage() ;
}

//获取数据库访问的错误信息
LPCTSTR CDBConnection::GetDBConnectionErrorMsg(void)
{      
 try
 {
  m_strConnErrorMsg.Empty() ;
  if (!m_pConnImpl->isValid())
  {
   SetErrorMessage(CONNCTION_INVALIDHANDLE,__FILE__,__LINE__) ;
   return (LPCTSTR)m_strConnErrorMsg ;
  }
  ErrorPtr pErr  = NULL;
  if( (DBCONNECTIONPtr->Errors->Count) > 0)
  {
   long nCount = DBCONNECTIONPtr->Errors->Count;

   // Collection ranges from 0 to nCount -1.
   CString strTempMsg ;
   for( long i = 0; i < nCount; i++)   
   {
    pErr = DBCONNECTIONPtr->Errors->GetItem(i);
    strTempMsg.Format(_T("Error number: %x\tError Message: %s\r\n"), pErr->Number, (LPCSTR) pErr->Description);
    m_strConnErrorMsg += strTempMsg ;
   }
  }   
 }
 catch (_com_error &e)
 {
  SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
 }
 catch (...)
 {
  SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
 } 
 return (LPCTSTR)m_strConnErrorMsg ;
}

BOOL CDBConnection::CloneTo(CDBConnection& toConnection)
{
 toConnection = *this ;
 //释放复制来的连接
 if(IsOpened())
 {
  toConnection.Close() ;
  //重新打开连接
  return toConnection.Open() ;
 }
 return TRUE ;
}

#undef DBCONNECTIONPtr

//end of  DBConnection.cpp

本文地址:http://com.8s8s.com/it/it494.htm