前段时间的一个项目中使用了ADO来操作数据库,总觉得每次使用起来都比较麻烦,计划抽点时间写个可以很方便使用的ADO封装类,现在终于写出了一个雏形,有什么不足之处还请各位多多指正。
这段代码中有两个类,CADODataConn中封装了一些使用ADO对数据库的操作,CRecordDBImpl中封装了一使用CADORecordBinding做数据库字段绑定操作时所需要的类。
现在这个类刚刚完成,还不成熟,希望大家多提意见,我会尽力完善它的。
编写这些代码的目的是使用Visual C++ Extensions for ADO 的数据库操作更加方便。
#pragma
once

#import
"
C:Program FilesCommon FilesSystemADOmsado15.dll
"
rename(
"
EOF
"
,
"
EndOfFile
"
) rename(
"
BOF
"
,
"
FirstOfFile
"
)
#import
"
C:Program FilesCommon Filessystemadomsadox.dll
"
#include
<
objbase.h
>
#include
<
initguid.h
>
#include
<
adoid.h
>
//
类和接口标识
#include
<
adoint.h
>
//
ADO 接口
#include
<
icrsint.h
>
//
ADO2.0 数据绑定扩展
#include
<
string
>

class
CADODataConn

...
{
public:
enum DB_ERROR_TYPE

...{
DB_SUCCESS = 0, // 成功
DB_BOF = -1, // 记录为第一条
DB_EOF = -2, // 记录为最后一条
DB_EMPTY = -3, // 记录集为空
DB_ERROR = -4 // 未知错误?
};
protected:
CADODataConn(void);
public:
CADODataConn(const char v_szDBName[], const char v_szUserName[], const char v_szPassword[],const char v_szTableName[]);
virtual ~CADODataConn(void);
private:
std::string m_strTableName;
std::string m_strPassword;
std::string m_strUserName;
std::string m_strDBName;
private:
ADODB::_ConnectionPtr m_pConn;
ADODB::_RecordsetPtr m_pRecordset;
IADORecordBinding* m_pRecordBinding;
public:
int ConnectDB(CADORecordBinding* const v_pRecordRs);
int MoveFirst(void);
BOOL IsEOF(void);
BOOL IsBOF(void);
int MoveLast(void);
int MoveNext(void);
int MovePrev(void);
int ExecuteSql(const char v_szSql[]);
int AddNew(CADORecordBinding* const v_pRecordRs);
int Update(CADORecordBinding* const v_pRecordRs);
void ReportComErr(_com_error& e, char v_szErrorInfo[]);
void PrintProviderError(char v_szErrorInfo[]);
int SelectRecordSet(const char v_szSqlCon[], CADORecordBinding* const v_pRecordRs);
void DisconnectDB(void);
}
;
#include
"
StdAfx.h
"
#include
"
.adodataconn.h
"

#include
<
strstream
>
#include
<
string
>


inline
void
TESTHR(HRESULT x)
...
{if FAILED(x) _com_issue_error(x);}
;

CADODataConn::CADODataConn(
void
)
: m_pConn(NULL)
, m_pRecordset(NULL)
, m_pRecordBinding(NULL)

...
{
::CoInitialize( NULL );
}

CADODataConn::
~
CADODataConn(
void
)

...
{
this->DisconnectDB();
}

CADODataConn::CADODataConn(
const
char
v_szDBName[],
const
char
v_szUserName[],
const
char
v_szPassword[],
const
char
v_szTableName[])
: m_pConn(NULL)
, m_pRecordset(NULL)
, m_pRecordBinding(NULL)

...
{
::CoInitialize( NULL );
m_strDBName = v_szDBName;
m_strUserName = v_szUserName;
m_strPassword = v_szPassword;
m_strTableName = v_szTableName;
}

int
CADODataConn::ConnectDB(CADORecordBinding
*
const
v_pRecordRs)

...
{
HRESULT hr = S_OK;

//try
//{
TESTHR( hr = m_pConn.CreateInstance( __uuidof( ADODB::Connection ) ) );
TESTHR( hr = m_pRecordset.CreateInstance( __uuidof( ADODB::Recordset) ) );

TESTHR( m_pConn->Open( m_strDBName.c_str(),
m_strUserName.c_str(),
m_strPassword.c_str(),
ADODB::adConnectUnspecified));
TESTHR( m_pRecordset->Open( m_strTableName.c_str(),
m_pConn.GetInterfacePtr(),
ADODB::adOpenDynamic,
ADODB::adLockOptimistic,
ADODB::adCmdText
));
TESTHR( m_pRecordset->QueryInterface(
__uuidof(IADORecordBinding),
(LPVOID*)&m_pRecordBinding
));
TESTHR( m_pRecordBinding->BindToRecordset( v_pRecordRs ) );
//}
//catch(_com_error &e)
//{
// e.Description();
// return DB_ERROR;
//}

return DB_SUCCESS;
}

int
CADODataConn::MoveFirst(
void
)

...
{
assert( NULL != m_pRecordset );
TESTHR( m_pRecordset->MoveFirst() );
if( IsEOF() && IsBOF() )

...{
return DB_EMPTY;
}
return DB_SUCCESS;
}

inline BOOL CADODataConn::IsEOF(
void
)

...
{// VARIANT_BOOL类型与BOOL类型定义上有区别
return FALSE != m_pRecordset->EndOfFile;
}
inline BOOL CADODataConn::IsBOF(
void
)

...
{// VARIANT_BOOL类型与BOOL类型定义上有区别
return FALSE != m_pRecordset->FirstOfFile;
}

int
CADODataConn::MoveLast(
void
)

...
{
assert( NULL != m_pRecordset );

TESTHR( m_pRecordset->MoveLast() );
if( IsEOF() && IsBOF() )

...{
return DB_EMPTY;
}
return DB_SUCCESS;
}

int
CADODataConn::MoveNext(
void
)

...
{
assert( NULL != m_pRecordset );

TESTHR( m_pRecordset->MoveNext() );
if( IsEOF() )

...{
if( IsBOF())
return DB_EMPTY;
return DB_EOF;
}
return DB_SUCCESS;
}

int
CADODataConn::MovePrev(
void
)

...
{
assert( NULL != m_pRecordset );

TESTHR( m_pRecordset->MovePrevious() );
if( IsBOF() )

...{
if( IsEOF() )
return DB_EMPTY;
return DB_BOF;
}
return DB_SUCCESS;
}
int
CADODataConn::ExecuteSql(
const
char
v_szSql[])

...
{
assert( NULL != m_pConn );

_variant_t RecordsAffected;

m_pConn->Execute( v_szSql, &RecordsAffected, adCmdText );

return DB_SUCCESS;
}

int
CADODataConn::AddNew(CADORecordBinding
*
const
v_pRecordRs)

...
{
assert( NULL != v_pRecordRs );
assert( NULL != m_pRecordBinding );

TESTHR( m_pRecordBinding->AddNew( v_pRecordRs ) );

return DB_SUCCESS;
}

int
CADODataConn::Update(CADORecordBinding
*
const
v_pRecordRs)

...
{
assert( NULL != v_pRecordRs );
assert( NULL != m_pRecordBinding );

TESTHR( m_pRecordBinding->Update( v_pRecordRs ) );

return DB_SUCCESS;
}

void
CADODataConn::ReportComErr(_com_error
&
e,
char
v_szErrorInfo[])

...
{
_variant_t vtConnect;
std::ostrstream strErrorInfo;
if( m_pRecordset != NULL )

...{
m_pRecordset->get_ActiveConnection( &vtConnect );
}
else

...{
strErrorInfo << "Error:" << std::endl;
strErrorInfo << "Code = " << std::hex << e.Error() << std::endl;
strErrorInfo << "Message = " << e.ErrorMessage() << std::endl;
::strcpy( v_szErrorInfo, strErrorInfo.str() );
return;
}


switch( vtConnect.vt )

...{
case VT_BSTR:

strErrorInfo << "Error:" << std::endl;
strErrorInfo << "Code = " << std::hex << e.Error() << std::endl;
strErrorInfo << "Message = " << e.ErrorMessage() << std::endl;
strErrorInfo << "Source = " << (LPCSTR)e.Source() << std::endl;
strErrorInfo << "Description = " << (LPCSTR)e.Description() << std::endl;
::strcpy( v_szErrorInfo, strErrorInfo.str() );
break;

case VT_DISPATCH:

PrintProviderError( v_szErrorInfo );
break;

default:

::strcpy( v_szErrorInfo, "访问数据库时发生未知错误!" );
break;
}
}

void
CADODataConn::PrintProviderError(
char
v_szErrorInfo[])

...
{
ADODB::ErrorPtr pErr = NULL;
long nCount = 0;
long i = 0;
std::ostrstream strErrorInfo;

if( (m_pConn->Errors->Count) > 0)

...{
nCount = m_pConn->Errors->Count;
// Collection ranges from 0 to nCount -1.
for(i = 0; i < nCount; i++)

...{
pErr = m_pConn->Errors->GetItem(i);
strErrorInfo << "Error Number:" << std::ios::hex << pErr->Number << std::endl;
strErrorInfo << " " << pErr->Description << std::endl;
}
}
::strcpy( v_szErrorInfo, strErrorInfo.str() );
}

int
CADODataConn::SelectRecordSet(
const
char
v_szSqlCon[],
CADORecordBinding
*
const
v_pRecordRs)

...
{
assert( NULL != v_pRecordRs );
m_pRecordset.Release();
if(NULL != m_pRecordBinding)
delete m_pRecordBinding;
m_pRecordBinding = NULL;

if( m_pConn == NULL )

...{// 没用数据库接连时,创建一个新的数据库接连
TESTHR( m_pConn.CreateInstance( __uuidof( ADODB::Connection ) ) );
TESTHR( m_pConn->Open( m_strDBName.c_str(),
m_strUserName.c_str(),
m_strPassword.c_str(),
ADODB::adConnectUnspecified));
}

// >>> 连接数据集 邱长丰增加. 2007-1-30 10:55
TESTHR( m_pRecordset.CreateInstance( __uuidof( ADODB::Recordset ) ) );
TESTHR( m_pRecordset->Open( v_szSqlCon,
m_pConn.GetInterfacePtr(),
ADODB::adOpenDynamic,
ADODB::adLockOptimistic,
ADODB::adCmdText
));
// >>> 绑定记录集 邱长丰增加. 2007-1-30 10:55
TESTHR( m_pRecordset->QueryInterface(
__uuidof(IADORecordBinding),
(LPVOID*)&m_pRecordBinding
));
TESTHR( m_pRecordBinding->BindToRecordset( v_pRecordRs ) );
return 0;
}

void
CADODataConn::DisconnectDB(
void
)

...
{
if( NULL != m_pRecordBinding )

...{
m_pRecordBinding->Release();
m_pRecordBinding = NULL;
}
if( NULL != m_pRecordset )

...{
if( ADODB::adStateOpen == m_pRecordset->GetState() )

...{
m_pRecordset->Close();
}
m_pRecordset = NULL;
}
if( NULL != m_pConn )

...{
if( ADODB::adStateOpen == m_pConn->GetState() )

...{
m_pConn->Close();
}
m_pConn = NULL;
}
}
#pragma
once

#include
<
memory
>
#include
<
assert.h
>
#include
"
ADODataConn.h
"

template
<
typename RS, typename _tagRecordData
=
RS
>
class
CRecordDBImpl

...
{
public:
CRecordDBImpl(void)
: m_pDataConn(NULL)

...{
}
virtual ~CRecordDBImpl(void)

...{
}
protected:
std::auto_ptr<CADODataConn> m_pDataConn;
RS m_recordRS;
public:
int InitDB(const char v_szDBName[], const char v_szUserName[], const char v_szPassword[], const char v_szTableName[])

...{
try

...{
m_pDataConn =
std::auto_ptr< CADODataConn >(
new CADODataConn( v_szDBName,
v_szUserName,
v_szPassword,
v_szTableName )
);
m_pDataConn->ConnectDB( &m_recordRS );
}
catch ( _com_error e)

...{
char szError[1024];
m_pDataConn->ReportComErr( e, szError );
return CADODataConn::DB_ERROR;
}
return CADODataConn::DB_SUCCESS;
}

int MoveFirst(void)

...{
assert( m_pDataConn.get() != NULL );
int iRet;
try

...{
iRet = m_pDataConn->MoveFirst();
}
catch( _com_error& e )

...{
char szError[1024];
m_pDataConn->ReportComErr( e, szError );
iRet = CADODataConn::DB_ERROR;
}
return iRet;
}
int MoveLast(void)

...{
assert( NULL != m_pDataConn );
int iRet = CADODataConn::DB_SUCCESS;
try

...{
iRet = m_pDataConn->MoveLast();
}
catch( _com_error& e )

...{
char szError[1024];
m_pDataConn->ReportComErr( e, szError );
iRet = CADODataConn:DB_ERROR;
}
return iRet;
}
int MoveNext(void)

...{
assert( NULL != m_pDataConn );
int iRet = CADODataConn::DB_SUCCESS;
try

...{
iRet = m_pDataConn->MoveNext();
}
catch( _com_error& e )

...{
char szError[1024];
m_pDataConn->ReportComErr( e, szError );
iRet = CADODataConn:DB_ERROR;
}
return iRet;
}
int MovePrev(void)

...{
assert( NULL != m_pDataConn );
int iRet = CADODataConn::DB_SUCCESS;
try

...{
iRet = m_pDataConn->MovePrev();
}
catch( _com_error& e )

...{
char szError[1024];
m_pDataConn->ReportComErr( e, szError );
iRet = CADODataConn:DB_ERROR;
}
return iRet;
}
int AddRecord( const _tagRecordData& v_recordData )

...{
assert( m_pDataConn.get() != NULL );
int iRet = CADODataConn::DB_SUCCESS;
try

...{
m_recordRS.SetData( v_recordData );
m_pDataConn->AddNew( &m_recordRS );
}
catch( _com_error& e )

...{
char szError[1024];
m_pDataConn->ReportComErr( e, szError );
iRet = CADODataConn::DB_ERROR;
}
return iRet;
}
int UpdateRecord( RS& v_recordBinding )

...{
assert( m_pDataConn.get() != NULL );
int iRet = CADODataConn::DB_SUCCESS;
try

...{
iRet = m_pDataConn->Update( &v_recordBinding );
}
catch( _com_error& e )

...{
char szError[1024];
m_pDataConn->ReportComErr( e, szError );
iRet = CADODataConn::DB_ERROR;
}
return iRet;
}
}
;