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