📄 accessdatabase.cpp
字号:
// AccessDatabase.cpp: implementation of the CComAccessMdb class.
//
//////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <comdef.h>
#include <stddef.h>
#include <assert.h>
#include <tchar.h>
#include <stdio.h>
#include <initguid.h>
#include "adoint.h"
#include "adoid.h"
#include "AccessMdb_i.h"
#include "AccessDatabase.h"
///////////////////////////////////////////////////////////////////
extern long g_LockCount;
////////////////////////////////////////////////////////////////////////
#ifndef CLOSE
#define CLOSE(padoSet) \
padoSet->Close(),padoSet->Release(),padoSet = 0;
#endif
#ifndef FREESTRING
#define FREESTRING(bstr) \
if( bstr ){\
SysFreeString(bstr); \
bstr = 0 ;\
}
#endif
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////错误处理//////////////////////////////////////
//对表达式exp的返回值进行检查,如果执行失败,则抛出失败值
#define THROW_ERR(exp) \
if ( FAILED( hr = (exp) ) ) \
throw hr;
//////////////////////////////////////////////////////////////////////
#define MAX_CACHESIZE 100
#define MAX_CONNECTSIZE 512
//////////////////////////////////////////////////////////////////////
CComAccessMdb::CComAccessMdb()
{
m_padoConnect = 0;
m_padoSet = 0;
m_dwRef = 0;
g_LockCount++;
/*
m_bstrDSN = 0;
m_bstrUserName = 0;
m_bstrPassword = 0;
m_bstrDriver = 0;
m_bstrServer = 0;
m_bstrDatabase = 0;*/
}
CComAccessMdb::~CComAccessMdb()
{
g_LockCount--;
//CloseDatabase();
}
STDMETHODIMP CComAccessMdb::QueryInterface(REFIID riid, LPVOID* ppVoid)
{
if ( IsEqualIID( riid, IID_IUnknown ) )
*ppVoid = static_cast<IAccessMdb *>(this);
else if( IsEqualIID( riid, __uuidof(IAccessMdb) ) )
*ppVoid = static_cast<IAccessMdb *>(this);
else
return (*ppVoid = 0), E_NOINTERFACE;
reinterpret_cast<IUnknown *>(*ppVoid)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) CComAccessMdb::AddRef(void)
{
return InterlockedIncrement(&m_dwRef);
}
STDMETHODIMP_(ULONG) CComAccessMdb::Release(void)
{
LONG ref = InterlockedDecrement(&m_dwRef);
if( ref == 0 )
{
CloseDatabase();
delete this;
}
return ref;
}
////////////////////////////////////////////////////////////////////
//
// IAccessDatabase public
//
////////////////////////////////////////////////////////////////////
HRESULT CComAccessMdb::OpenDatabaseWithDSN (
BSTR bstrDSN,
BSTR bstrUserName,
BSTR bstrPassword )
{
CloseDatabase();
wchar_t wszConnect[MAX_CONNECTSIZE];
int len = swprintf( wszConnect, OLESTR("DSN=%s;UID=%s;PWD=%s;"),
bstrDSN, bstrUserName, bstrPassword );
BSTR bstr;
bstr = SysAllocStringLen( 0, len*sizeof(TCHAR) );
wcscpy(bstr, wszConnect);
HRESULT hr = OpenDatabase(bstr);
SysFreeString(bstr);
return hr;
/*
m_bstrDSN = SysAllocString(bstrDSN);
m_bstrUserName = SysAllocString(bstrUserName);
m_bstrPassword = SysAllocString(bstrPassword);
return OpenDatabase()? S_OK:E_FAIL;*/
}
HRESULT CComAccessMdb::OpenDatabaseWithDriver (
BSTR bstrDriver,
BSTR bstrServer,
BSTR bstrDatabase,
BSTR bstrUserName,
BSTR bstrPassword )
{
CloseDatabase();
wchar_t wszConnect[MAX_CONNECTSIZE];
int len = swprintf( wszConnect, OLESTR("driver={%s};server=%s;uid=%s;pwd=%s;database=%s"),
bstrDriver, bstrServer, bstrUserName, bstrPassword, bstrDatabase );
BSTR bstr;
bstr = SysAllocStringLen( 0, len*sizeof(TCHAR) );
wcscpy(bstr, wszConnect);
HRESULT hr = OpenDatabase(bstr);
SysFreeString(bstr);
return hr;
/* m_bstrDriver = SysAllocString(bstrDriver);
m_bstrServer = SysAllocString(bstrServer);
m_bstrDatabase = SysAllocString(bstrDatabase);
m_bstrUserName = SysAllocString(bstrUserName);
m_bstrPassword = SysAllocString(bstrPassword);
return (OpenDatabase()? S_OK:E_FAIL);*/
}
HRESULT CComAccessMdb::OpenDatabaseWithConnectUDL( BSTR bstrConnectUDL )
{
CloseDatabase();
return OpenDatabase(bstrConnectUDL);
}
HRESULT CComAccessMdb::CloseDatabase ()
{
if( m_padoConnect != 0 )
CLOSE(m_padoConnect);
if( m_padoSet != 0 )
CLOSE(m_padoSet);
/* FREESTRING(m_bstrDSN);
FREESTRING(m_bstrUserName);
FREESTRING(m_bstrPassword);
FREESTRING(m_bstrDriver);
FREESTRING(m_bstrServer);
FREESTRING(m_bstrDatabase);*/
return S_OK;
}
HRESULT CComAccessMdb::Select (
BSTR bstrSQL,
long * plRow,
long * plCol,
VARIANT ** ppVar )
{
assert( ppVar && plRow && plCol );
*plRow = *plCol= 0;
*ppVar = 0;
HRESULT hr;
//连接数据库
if( !m_padoConnect )
return E_FAIL;
m_padoSet = 0;
//选出记录集
hr = OpenRecordset( &m_padoSet, bstrSQL );
if( hr != S_OK )
return hr;
assert(m_padoSet);
//得到记录数
long row = 0;
long field = 0;
ADOFields * padoFields = 0;
//得到字段数量和记录数量
m_padoSet->get_RecordCount(&row);
m_padoSet->get_Fields(&padoFields);
assert(padoFields);
if( padoFields == 0 )
{
CLOSE(m_padoSet);
return E_FAIL;
}
padoFields->get_Count(&field);
if( row==0 || field==0 )
{
CLOSE(m_padoSet);
padoFields->Release();
return S_FALSE;
}
//分配内存
VARIANT *pvar = (VARIANT *)CoTaskMemAlloc( row*field*sizeof(VARIANT) );
if(pvar == 0)
{
CLOSE(m_padoSet);
padoFields->Release();
return E_OUTOFMEMORY;
}
//得到字段类型
long i=0, j=0, pos=0;
//DataTypeEnum * pdType = new DataTypeEnum[field];
//ADOField ** ppadoField = new ADOField*[field];
//_variant_t ivar(0L);
/*for(j=0; j<field; j++)
{
ppadoField[j] = 0;
ivar.lVal = j;
padoFields->get_Item(ivar, ppadoField+j);
assert(ppadoField[j]);
if( ppadoField[j] == 0 )
{
CLOSE(padoSet);
padoFields->Release();
//delete[] pdType;
while(--j>0)
ppadoField[j]->Release();
delete[] ppadoField;
return S_FALSE;
}
//ppadoField[j]->get_Type(pdType+j);
}
*/
//得到字段中的数据
_variant_t vIndex(0L);
for(i=0; i<row; i++)
{
for(j=0; j<field; j++)
{
pos = i*field+j;
vIndex.lVal = j;
try{
THROW_ERR((m_padoSet->get_Collect(vIndex, &pvar[pos])))
}
catch( HRESULT hr ) {
//m_error.GetError(hr);
CLOSE(m_padoSet);
padoFields->Release();
return hr;
}
//TRY_EXEC( m_padoSet->get_Collect(vIndex, &pvar[pos]) );
}
m_padoSet ->MoveNext();
}
*plRow = row;
*plCol = field;
*ppVar = pvar;
CLOSE(m_padoSet);
padoFields->Release();
/* for(j=0; j<field; j++)
ppadoField[j]->Release();
delete[] ppadoField;*/
return S_OK;
}
HRESULT CComAccessMdb::Execute ( BSTR bstrSQL )
{
//连接数据库
if( !m_padoConnect )
return E_FAIL;
//long level;
HRESULT hr;
//m_padoConnect->BeginTrans(&level);
try{
THROW_ERR( m_padoConnect->Execute( bstrSQL, 0, adCmdText, 0 ));
}
catch(HRESULT hr)
{
//m_error.GetError(hr);
//m_padoConnect->RollbackTrans();
return hr;
}
//m_padoConnect->CommitTrans();
return S_OK;
}
HRESULT CComAccessMdb::BeginTS()
{
long level;
HRESULT hr;
if( !m_padoConnect )
return E_FAIL;
try{
THROW_ERR( m_padoConnect->BeginTrans(&level) );
}
catch(HRESULT hr)
{
//m_error.GetError(hr);
return hr;
}
return S_OK;
}
HRESULT CComAccessMdb::CommitTS()
{
HRESULT hr;
if( !m_padoConnect )
return E_FAIL;
try{
THROW_ERR( m_padoConnect->CommitTrans() );
}
catch(HRESULT hr)
{
//m_error.GetError(hr);
return hr;
}
return S_OK;
}
HRESULT CComAccessMdb::RollbackTS()
{
HRESULT hr;
if( !m_padoConnect )
return E_FAIL;
try{
THROW_ERR( m_padoConnect->RollbackTrans() );
}
catch(HRESULT hr)
{
//m_error.GetError(hr);
return hr;
}
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
HRESULT CComAccessMdb::OpenDatabase( BSTR bstrConnect)
{
if( m_padoConnect )
return S_OK;
HRESULT hr;
try{
THROW_ERR( CoCreateInstance( CLSID_CADOConnection,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADOConnection,
(LPVOID *)&m_padoConnect ) );
THROW_ERR( m_padoConnect->put_ConnectionString(bstrConnect) );
THROW_ERR( m_padoConnect->Open( OLESTR(""),
OLESTR(""),//m_bstrUserName,
OLESTR(""),//m_bstrPassword,
adOpenUnspecified ) );
}
catch (HRESULT hr)
{
//m_error.GetError(hr);
if( m_padoConnect != 0 )
CLOSE(m_padoConnect);
return hr;
}
return S_OK;
}
HRESULT CComAccessMdb::OpenRecordset( struct _ADORecordset ** ppSet, BSTR bstrSQL )
{
assert( *ppSet == 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -