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

📄 sypodlobjects.cpp

📁 这是一个基于COM的数据库访问技术
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// SypODLObjects.cpp: implementation of the CSypODLObject classes.
//
//////////////////////////////////////////////////////////////////////
//
// CSypODLObjects are the set of classes that provide a very rich, 
// sophisticated, and user-friendly wrappers around ATL consumer 
// templates for OLEDB. These classes provide a lot of flexibility and
// functionality over OLEDB templates without loosing their power and  
// performance
//
// Author: G. Naik, GNaik@SypramTech.com (or Ghannaik@yahoo.com)
// You may freely use these classes in non-commercial products.These
// library is not to be sold for profit. 
//
// NOTE : Prior permission required by Sypram Technology (www.sypram.com)
// if you want to use this library in commercial projects. Send me an email
// if that is the case.
// 
// CopyRight(C)2001. Sypram Technology. WWW.SYPRAM.COM
// Version : 1.0
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#define INITGUID
#include <initguid.h>

#include "SypODLObjects.h"
#include <assert.h>
#include "resource.h"
#include <Math.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define SYPMSG_MAX_MSG_SIZE 2048


//********************************************************************************
/////////////////////  CSypODLException Object ////////////////////////////////
//********************************************************************************

CSypODLException::CSypODLException(UINT m_cause, HRESULT hr, CComPtr<IUnknown> m_spUnk)
{
	m_nCause = m_cause;
	m_nHr = hr;
	m_pUnknown = m_spUnk;
}

//********************************************************************************

void CSypODLException::GetError(CString& RetStr)
{
	CSypOLEDBErr mErr;
	TCHAR mError[2048], mErrNum[10];

	memset(mError, 0, sizeof(TCHAR) * 2048);

	if(m_nHr != 0)
	{
		mErr.GetHRRESULTMessage(m_nHr, mError);

		if(_tcsstr(mError, _T("No such interface supported")) != NULL \
			|| _tcsstr(mError, _T("Unspecified error")) != NULL  \
			|| _tcsstr(mError, _T("Errors occurred")) != NULL)
		{
			mError[0] = 0;

			if(!m_pUnknown)
				mErr.GetSingleError(mError);
			else
				if(mErr.AreDBErrorsSupported(m_pUnknown))
					mErr.GetDBErrors((CComPtr<struct IUnknown>)m_pUnknown, mError);	
		}
	}
	
	CString str;
	
	if(!str.LoadString(m_nCause))
		str = _T("(Unable to load error string)");

	lstrcat(mError, _T("\n"));
	lstrcat(mError, str); 

	_itot(m_nCause, mErrNum, 10);

	RetStr = CString("Errorcode : ") + CString(mErrNum) + CString("\n");
	RetStr += mError;
}

//********************************************************************************

void CSypODLException::DisplayError()
{
	CString str;

	GetError(str);
	::MessageBox(NULL, str, _T("Error"), MB_OK + MB_ICONSTOP);
}

//********************************************************************************
/////////////////////  CSypOLEDBConnection Object ////////////////////////////////
//********************************************************************************

CSypODLConnection::CSypODLConnection()
{
	m_Provider = "MSDASQL";
	m_bEnableThrow = true;
	m_bIsOpen = false;
}

//********************************************************************************

CSypODLConnection::~CSypODLConnection()
{
	Close();
}

//********************************************************************************

bool CSypODLConnection::IsOpen()
{
	return m_bIsOpen;
}

//********************************************************************************

void CSypODLConnection::SetProvider(CString mProv)
{
	assert(!mProv.IsEmpty());
	m_Provider = mProv;
}

//********************************************************************************

bool CSypODLConnection::Open(CString m_DSN, CString m_UID, CString m_PWD)
{
	if(m_bIsOpen)
		Close();
	
	CDBPropSet	dbinit(DBPROPSET_DBINIT);

	dbinit.AddProperty(DBPROP_AUTH_PASSWORD, m_PWD);
	dbinit.AddProperty(DBPROP_AUTH_USERID, m_UID);
	dbinit.AddProperty(DBPROP_INIT_DATASOURCE, m_DSN);
	dbinit.AddProperty(DBPROP_INIT_PROMPT, (short)4);
	dbinit.AddProperty(DBPROP_INIT_LCID, (long)1033);

	hr = m_db.OpenWithServiceComponents(m_Provider, &dbinit);
	if (FAILED(hr))
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_CONTOPENDB, hr);
		return false;
	}

	hr = m_session.Open(m_db);
	if (FAILED(hr))
	{
		m_db.Close();
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_CONTOPENSESSION, hr);
		return false;
	}

	m_bIsOpen = true;
	return true;
}

//********************************************************************************

bool CSypODLConnection::Open(CDBPropSet dbinit)
{
	if(m_bIsOpen)
		Close();

	hr = m_db.OpenWithServiceComponents(m_Provider, &dbinit);
	if (FAILED(hr))
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_CONTOPENDB, hr);
		return false;
	}

	hr = m_session.Open(m_db);
	if (FAILED(hr))
	{
		m_db.Close();
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_CONTOPENSESSION, hr);
		return false;
	}

	m_bIsOpen = true;
	return true;
}

//********************************************************************************

void CSypODLConnection::Close()
{
	if(m_bIsOpen)
	{
		m_bIsOpen = false;
		m_session.Close();
		m_db.Close();
	}
}

//********************************************************************************

bool CSypODLConnection::StartTransaction(ISOLEVEL isoLevel /*=ISOLATIONLEVEL_READCOMMITTED*/, \
										 ULONG isoFlags /*=0*/)
{
	if(!m_bIsOpen)
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_DBNOTOPEN, NULL);
		return false;
	}

	hr = m_session.StartTransaction(isoLevel, isoFlags);
	if(FAILED(hr))
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_STARTTRANSFAILED, hr);
		return false;
	}

	return true;
}

//********************************************************************************

bool CSypODLConnection::Abort(BOID	*pboidReason)
{
	if(!m_bIsOpen)
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_DBNOTOPEN, NULL);
		return false;
	}

	hr = m_session.Abort(pboidReason);
	if(FAILED(hr))
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_ABORTTRANSFAILED, hr);
		return false;
	}

	return true;
}

//********************************************************************************

bool CSypODLConnection::Commit(BOOL bRetaining /*=FALSE*/, DWORD grfTC/*=XACTTC_SYNC*/, \
							   DWORD grfRM/*=0*/)
{
	if(!m_bIsOpen)
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_DBNOTOPEN, NULL);
		return false;
	}

	hr = m_session.Commit(bRetaining, grfTC, grfRM);
	if(FAILED(hr))
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_COMMITTRANSFAILED, hr);
		return false;
	}

	return true;
}

//********************************************************************************

bool CSypODLConnection::Execute(CString sSQL)
{
	if(!m_bIsOpen)
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_DBNOTOPEN, NULL);
		return false;
	}

	CCommand<CNoAccessor, CNoRowset>	mRs;

	hr = mRs.Open(m_session, sSQL);
	if(FAILED(hr))
	{
		if(m_bEnableThrow)
			throw CSypODLException(IDS_SYPODL_ERR_EXECUTEFAILED, hr);
		return false;
	}

	mRs.Close();

	return true;
}


//********************************************************************************
/////////////////////  CSypOLEDBErr Object ///////////////////////////////////////
//********************************************************************************

bool CSypOLEDBErr::AreDBErrorsSupported(CComPtr<IUnknown> m_spUnk)
{
	CComPtr<ISupportErrorInfo> spSupportErrorInfo;

	if (SUCCEEDED(m_spUnk->QueryInterface(IID_ISupportErrorInfo,(void **) &spSupportErrorInfo))) 
	{
		if (SUCCEEDED(spSupportErrorInfo->InterfaceSupportsErrorInfo(IID_ICommandPrepare)))
			return true;
	}
	return true;
}

//*******************************************************************************

bool CSypOLEDBErr::GetDBErrors(CComPtr<IUnknown> m_spUnk, TCHAR  *msg)
{
	CDBErrorInfo errInfo;
	IErrorInfo *pErrorInfo = NULL;
	BSTR pErrorDescription = NULL;
	ULONG ulRecords = 0;

	try
	{
		HRESULT hr = errInfo.GetErrorRecords(m_spUnk, IID_ICommandPrepare, &ulRecords);
		if (FAILED(hr) || hr == S_FALSE || ulRecords == 0) 
		{
			//The error info object could not be retrieved
			_tcscat(msg, _T("\n\nUnable to retrieve error details."));
		}
		else 
		{
			// Error info object was retrieved successfully
			LCID lcid = GetUserDefaultLCID();
			for (ULONG loop = 0; loop < ulRecords; loop ++) 
			{
				// Get the error information from the source
				hr = errInfo.GetErrorInfo(loop, lcid, &pErrorInfo);
				if (FAILED(hr)) 
				{
					continue;
				}
				//Get the error description
				pErrorInfo->GetDescription(&pErrorDescription);
				//Convert error description to single-width character
				_stprintf(msg, _T("%s\n\n%S"), msg, pErrorDescription);
				//Get SQLState and Error Code
				GetSQLCodes(msg, &errInfo, loop);
				//Clean up
				SysFreeString(pErrorDescription);
				pErrorInfo->Release();
			}
		}
	}
	catch(...)
	{
		_tcscat(msg, _T("Internal error occurred. (GetDBErrors)"));		
		return false;
	}

	return true;
}

//*********************************************************************************

bool CSypOLEDBErr::GetSingleError(TCHAR    *msg) 
{
	IErrorInfo *pErrorInfo = NULL;
	BSTR pErrorDescription = NULL;

	try
	{
		if (SUCCEEDED(GetErrorInfo(0, &pErrorInfo))) 
		{
			if (SUCCEEDED(pErrorInfo->GetDescription(&pErrorDescription))) 
			{
				_stprintf(msg, _T("%s\n\n%S"), msg, pErrorDescription);

				SysFreeString(pErrorDescription);
			}
			else 
				_tcscat(msg, _T("Could not find the error description"));

			pErrorInfo->Release();
		}
		else 
			_tcscat(msg, _T("Could not retrieve error information"));
	}
	catch(...)
	{
		_tcscat(msg, _T("Internal error occurred. (GetSingleError)"));		
		return false;
	}

	return true;
}

//*********************************************************************************

bool CSypOLEDBErr::GetSQLCodes(TCHAR    *msg, CDBErrorInfo *errInfo, ULONG errorNum)
{
	CComPtr<ISQLErrorInfo> spSQLErrorInfo;
	TCHAR  SQLState[100];	//Buffer for error message

	try
	{
		if (SUCCEEDED(errInfo->GetCustomErrorObject(errorNum, 
					IID_ISQLErrorInfo, (IUnknown**) &spSQLErrorInfo))) 
		{
			BSTR bstrSQLState = NULL;	//SQLState that's returned
			LONG errorCode;		//SQL Code that's returned

			if (SUCCEEDED(spSQLErrorInfo->GetSQLInfo(&bstrSQLState, &errorCode))) 
			{
				_stprintf(SQLState, _T("\n\nSQLState is %S\nError code is %ld"),	bstrSQLState, errorCode);
				
				_tcscat(msg, SQLState);
				SysFreeString(bstrSQLState);	//Clean up
			}
			else 
				_tcscat(msg, _T("\n\nCould not get SQL details."));
		}
		else 
			_tcscat(msg, _T("\n\nCould not get error or SQLState code."));
	}
	catch(...)
	{
		_tcscat(msg, _T("Internal error occurred. (GetSQLCodes)"));		
		return false;
	}

	return true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -