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

📄 accessdatabase.cpp

📁 访问数据的COM组件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -