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

📄 infclient.cpp

📁 通用的数据库中间库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// infClient.cpp: implementation of the IinfClient class.////////////////////////////////////////////////////////////////////////#include <SQLAPI.h>#include "infClient.h"#include <assert.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>	// strtol
 #include <infAPI.h>
#include "samisc.h"#include "errmsg.h"//////////////////////////////////////////////////////////////////////// IinfConnection Class//////////////////////////////////////////////////////////////////////class IinfConnection : public ISAConnection{	enum	{		MaxLongAtExecSize = 0x7fffffff+SQL_LEN_DATA_AT_EXEC(0)	};	friend class IinfCursor;	infConnectionHandles m_handles;	long m_nDriverODBCVer;	static void Check(		SQLRETURN return_code,		SQLSMALLINT HandleType,		SQLHANDLE Handle);	SQLINTEGER LenDataAtExec();	void issueIsolationLevel(		SAIsolationLevel_t eIsolationLevel);	void SafeAllocEnv();	void SafeAllocConnect();	void SafeFreeEnv();	void SafeFreeConnect();	void SafeSetEnvAttr();	void SafeCommit();	void SafeRollback();	void SafeSetConnectOption(		SQLINTEGER Attribute,		SQLPOINTER ValuePtr,		SQLINTEGER StringLength);protected:	virtual ~IinfConnection();public:	IinfConnection(SAConnection *pSAConnection);	virtual void InitializeClient();
	virtual void UnInitializeClient();

	virtual long GetClientVersion() const;	virtual long GetServerVersion() const;	virtual SAString GetServerVersionString() const;	virtual bool IsConnected() const;	virtual void Connect(		const SAString &sDBString,		const SAString &sUserID,		const SAString &sPassword);	virtual void Disconnect();	virtual void setIsolationLevel(		SAIsolationLevel_t eIsolationLevel);	virtual void setAutoCommit(		SAAutoCommit_t eAutoCommit);	virtual void Commit();	virtual void Rollback();	virtual saAPI *NativeAPI() const;	virtual saConnectionHandles *NativeHandles();	virtual ISACursor *NewCursor(SACommand *m_pCommand);	virtual void CnvtInternalToDateTime(		SADateTime &date_time,		const void *pInternal,		int nInternalSize);	static void CnvtInternalToDateTime(		SADateTime &date_time,		const TIMESTAMP_STRUCT &Internal);	static void CnvtDateTimeToInternal(		const SADateTime &date_time,		TIMESTAMP_STRUCT &Internal);

	virtual void CnvtInternalToCursor(
		SACommand *pCursor,
		const void *pInternal);
};//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////IinfConnection::IinfConnection(	SAConnection *pSAConnection) : ISAConnection(pSAConnection){	m_nDriverODBCVer = 0;}IinfConnection::~IinfConnection(){}
/*virtual */
void IinfConnection::InitializeClient()
{
	::AddInfSupport();
}

/*virtual */
void IinfConnection::UnInitializeClient()
{
	::ReleaseInfSupport();
}
SQLINTEGER IinfConnection::LenDataAtExec(){	SQLSMALLINT retlen = 0;	char szValue[10];	Check(g_infAPI.SQLGetInfo(		m_handles.m_hdbc, SQL_NEED_LONG_DATA_LEN, szValue, sizeof(szValue), &retlen), SQL_HANDLE_DBC, m_handles.m_hdbc);	if(retlen > 0 && (*szValue == 'Y' || *szValue == 'y'))		return SQL_LEN_DATA_AT_EXEC(MaxLongAtExecSize);	return SQL_DATA_AT_EXEC;}/*virtual */void IinfConnection::CnvtInternalToDateTime(	SADateTime &date_time,	const void *pInternal,	int nInternalSize){	assert(nInternalSize == sizeof(TIMESTAMP_STRUCT));
	if(nInternalSize != sizeof(TIMESTAMP_STRUCT))
		return;	CnvtInternalToDateTime(date_time, *(const TIMESTAMP_STRUCT*)pInternal);}/*static */void IinfConnection::CnvtInternalToDateTime(	SADateTime &date_time,	const TIMESTAMP_STRUCT &Internal){	date_time = SADateTime(
		Internal.year,
		Internal.month,
		Internal.day,
		Internal.hour,
		Internal.minute,
		Internal.second);

	date_time.Fraction() = Internal.fraction;
}/*static */void IinfConnection::CnvtDateTimeToInternal(	const SADateTime &date_time,	TIMESTAMP_STRUCT &Internal){	Internal.year = (SQLSMALLINT)(date_time.GetYear());
	Internal.month = (SQLUSMALLINT)(date_time.GetMonth());
	Internal.day = (SQLUSMALLINT)date_time.GetDay();
	Internal.hour = (SQLUSMALLINT)date_time.GetHour();
	Internal.minute = (SQLUSMALLINT)date_time.GetMinute();
	Internal.second = (SQLUSMALLINT)date_time.GetSecond();
	Internal.fraction = date_time.Fraction();}	
/*virtual */
void IinfConnection::CnvtInternalToCursor(
	SACommand * /*pCursor*/,
	const void * /*pInternal*/)
{
	assert(false);
}
/*virtual */long IinfConnection::GetClientVersion() const{	if(g_nInfDLLVersionLoaded == 0)	// has not been detected
	{
		if(IsConnected())
		{
			char sInfoValue[1024];
			SQLSMALLINT cbInfoValue;
			g_infAPI.SQLGetInfo(m_handles.m_hdbc, SQL_DRIVER_VER, sInfoValue, sizeof(sInfoValue), &cbInfoValue);
			sInfoValue[cbInfoValue] = 0;

			char *sPoint;
			short nMajor = (short)strtol(sInfoValue, &sPoint, 10);
			assert(*sPoint == '.');

			sPoint++;
			short nMinor = (short)strtol(sPoint, &sPoint, 10);
			return SA_MAKELONG(nMinor, nMajor);
		}
	}

	return g_nInfDLLVersionLoaded;
}/*virtual */long IinfConnection::GetServerVersion() const{	char sInfoValue[1024];	SQLSMALLINT cbInfoValue;	g_infAPI.SQLGetInfo(m_handles.m_hdbc, SQL_DBMS_VER, sInfoValue, sizeof(sInfoValue), &cbInfoValue);	sInfoValue[cbInfoValue] = 0;	char *sPoint;	short nMajor = (short)strtol(sInfoValue, &sPoint, 10);	assert(*sPoint == '.');	sPoint++;	short nMinor = (short)strtol(sPoint, &sPoint, 10);	return nMinor + (nMajor << 16);}/*virtual */SAString IinfConnection::GetServerVersionString() const{	char sInfoValue[1024];	SQLSMALLINT cbInfoValue;	g_infAPI.SQLGetInfo(m_handles.m_hdbc, SQL_DBMS_NAME, sInfoValue, sizeof(sInfoValue), &cbInfoValue);	SAString s = SAString(sInfoValue, cbInfoValue);	s += " Release ";	g_infAPI.SQLGetInfo(m_handles.m_hdbc, SQL_DBMS_VER, sInfoValue, sizeof(sInfoValue), &cbInfoValue);	s += SAString(sInfoValue, cbInfoValue);	return s;}/*static */void IinfConnection::Check(	SQLRETURN return_code,	SQLSMALLINT HandleType,	SQLHANDLE Handle){	if(return_code == SQL_SUCCESS)		return;	if(return_code == SQL_SUCCESS_WITH_INFO)		return;	SQLCHAR Sqlstate[5+1];	SQLINTEGER NativeError = 0;	char sMsg[4096] = "";	SQLSMALLINT TextLength;	SQLRETURN rc = 0;		if(g_infAPI.SQLGetDiagRec)	{		rc = g_infAPI.SQLGetDiagRec(HandleType, Handle, 1, 			Sqlstate, &NativeError,			(SQLCHAR *)sMsg, sizeof(sMsg), &TextLength);	}	else	{		switch(HandleType)		{		case SQL_HANDLE_ENV:			rc = g_infAPI.SQLError(				Handle,				NULL,				NULL,				Sqlstate, &NativeError,				(SQLCHAR *)sMsg, sizeof(sMsg), &TextLength);			break;		case SQL_HANDLE_DBC:			rc = g_infAPI.SQLError(				NULL,				Handle,				NULL,				Sqlstate, &NativeError,				(SQLCHAR *)sMsg, sizeof(sMsg), &TextLength);			break;		case SQL_HANDLE_STMT:			rc = g_infAPI.SQLError(				NULL,				NULL,				Handle,				Sqlstate, &NativeError,				(SQLCHAR *)sMsg, sizeof(sMsg), &TextLength);			break;		default:			assert(false);		}	}	switch(rc)	{	case SQL_INVALID_HANDLE:		strcpy(sMsg, "SQL_INVALID_HANDLE");		break;	case SQL_NO_DATA:		strcpy(sMsg, "SQL_NO_DATA");		break;	}	throw SAException(		SA_RDBMS_API_Error,		NativeError, -1,		"%s", sMsg);}/*virtual */bool IinfConnection::IsConnected() const{	return m_handles.m_hdbc != NULL;}void IinfConnection::SafeAllocEnv(){	if(g_infAPI.SQLAllocHandle)		g_infAPI.SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_handles.m_hevn);	else		g_infAPI.SQLAllocEnv(&m_handles.m_hevn);	assert(m_handles.m_hevn);}void IinfConnection::SafeAllocConnect(){	if(g_infAPI.SQLAllocHandle)		Check(g_infAPI.SQLAllocHandle(SQL_HANDLE_DBC, m_handles.m_hevn, &m_handles.m_hdbc), SQL_HANDLE_ENV, m_handles.m_hevn);	else		Check(g_infAPI. SQLAllocConnect(m_handles.m_hevn, &m_handles.m_hdbc), SQL_HANDLE_ENV, m_handles.m_hevn);}void IinfConnection::SafeFreeEnv(){	if(g_infAPI.SQLFreeHandle)		Check(g_infAPI.SQLFreeHandle(SQL_HANDLE_ENV, m_handles.m_hevn), SQL_HANDLE_ENV, m_handles.m_hevn);	else		Check(g_infAPI. SQLFreeEnv(m_handles.m_hevn), SQL_HANDLE_ENV, m_handles.m_hevn);	m_handles.m_hevn = NULL;}void IinfConnection::SafeFreeConnect(){	if(g_infAPI.SQLFreeHandle)		Check(g_infAPI.SQLFreeHandle(SQL_HANDLE_DBC, m_handles.m_hdbc), SQL_HANDLE_DBC, m_handles.m_hdbc);	else		Check(g_infAPI.SQLFreeConnect(m_handles.m_hdbc), SQL_HANDLE_DBC, m_handles.m_hdbc);	m_handles.m_hdbc = NULL;}void IinfConnection::SafeSetEnvAttr(){	if(g_infAPI.SQLSetEnvAttr)		Check(g_infAPI.SQLSetEnvAttr(m_handles.m_hevn, SQL_ATTR_ODBC_VERSION, SQLPOINTER(SQL_OV_ODBC3), 0), SQL_HANDLE_ENV, m_handles.m_hevn);}/*virtual */void IinfConnection::Connect(	const SAString &sDBString,	const SAString &sUserID,	const SAString &sPassword){	assert(!m_handles.m_hevn);	assert(!m_handles.m_hdbc);	SafeAllocEnv();	try	{		SafeSetEnvAttr();		SafeAllocConnect();		if(sDBString.Find('=') == -1)	// it's not a valid connection string, but it can be DSN name			Check(g_infAPI.SQLConnect(m_handles.m_hdbc, 				(SQLCHAR *)(const char*)sDBString, SQL_NTS,				(SQLCHAR *)(const char*)sUserID, SQL_NTS,				(SQLCHAR *)(const char*)sPassword, SQL_NTS),				SQL_HANDLE_DBC, m_handles.m_hdbc);		else
		{
			SAString s = sDBString;
			if(!sUserID.IsEmpty())
			{
				s += ";UID=";
				s += sUserID;
			}
			if(!sPassword.IsEmpty())
			{
				s += ";PWD=";
				s += sPassword;
			}
			Check(g_infAPI.SQLDriverConnect(				m_handles.m_hdbc, NULL,				(SQLCHAR *)(const char*)s, SQL_NTS, NULL, 0, 0, SQL_DRIVER_NOPROMPT),				SQL_HANDLE_DBC, m_handles.m_hdbc);
		}		char sVer[512];		SQLSMALLINT StringLength;		Check(g_infAPI. SQLGetInfo(			m_handles.m_hdbc,			SQL_DRIVER_ODBC_VER,			sVer,			sizeof(sVer),			&StringLength), SQL_HANDLE_DBC, m_handles.m_hdbc);		m_nDriverODBCVer = SAExtractVersionFromString(sVer);	}	catch(...)	{		// clean up		if(m_handles.m_hdbc)		{			try			{				SafeFreeConnect();			}			catch(SAException &)			{			}		}		if(m_handles.m_hevn)		{			try			{				SafeFreeEnv();			}			catch(SAException &)			{			}		}		throw;	}}/*virtual */void IinfConnection::Disconnect(){	assert(m_handles.m_hevn);	assert(m_handles.m_hdbc);	Check(g_infAPI.SQLDisconnect(m_handles.m_hdbc), SQL_HANDLE_DBC, m_handles.m_hdbc);	SafeFreeConnect();	SafeFreeEnv();	m_nDriverODBCVer = 0;}void IinfConnection::SafeCommit(){	if(g_infAPI.SQLEndTran)		Check(g_infAPI.SQLEndTran(SQL_HANDLE_DBC, m_handles.m_hdbc, SQL_COMMIT), SQL_HANDLE_DBC, m_handles.m_hdbc);	else		Check(g_infAPI. SQLTransact(m_handles.m_hevn, m_handles.m_hdbc, SQL_COMMIT), SQL_HANDLE_DBC, m_handles.m_hdbc);}void IinfConnection::SafeRollback(){	if(g_infAPI.SQLEndTran)		Check(g_infAPI.SQLEndTran(SQL_HANDLE_DBC, m_handles.m_hdbc, SQL_ROLLBACK), SQL_HANDLE_DBC, m_handles.m_hdbc);	else		Check(g_infAPI. SQLTransact(m_handles.m_hevn, m_handles.m_hdbc, SQL_ROLLBACK), SQL_HANDLE_DBC, m_handles.m_hdbc);}/*virtual */void IinfConnection::Commit(){	SafeCommit();}/*virtual */void IinfConnection::Rollback(){	SafeRollback();}//////////////////////////////////////////////////////////////////////// IinfClient Class////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////IinfClient::IinfClient(){}IinfClient::~IinfClient(){}ISAConnection *IinfClient::QueryConnectionInterface(	SAConnection *pSAConnection){	return new IinfConnection(pSAConnection);}//////////////////////////////////////////////////////////////////////// IinfCursor Class//////////////////////////////////////////////////////////////////////class IinfCursor : public ISACursor{	infCommandHandles	m_handles;	SAString CallSubProgramSQL();	SADataType_t CnvtNativeToStd(		int nNativeType,		int nNativeSubType,		int nSize,		int nPrec,		int nScale) const;	virtual int CnvtStdToNative(SADataType_t eDataType) const;	int CnvtStdToNativeValueType(SADataType_t eDataType) const;	void BindLongs();	void SafeAllocStmt();	void SafeFreeStmt();protected:	virtual unsigned int InputBufferSize(		const SAParam &Param) const;	virtual unsigned int OutputBufferSize(		SADataType_t eDataType,		unsigned int nDataSize) const;	virtual void SetFieldBuffer(		int nCol,	// 1-based		void *pInd,		unsigned int nIndSize,		void *pSize,		unsigned int nSizeSize,		void *pValue,		unsigned int nValueSize);	virtual bool IndicatorIsNull(		int nPos,	// 1-based		SAValueRead &vr,		ValueType_t eValueType,		void *pInd, unsigned int nIndSize,		void *pSize, unsigned int nSizeSize,		unsigned int &nRealSize,
		int nBulkReadingBufPos) const;

⌨️ 快捷键说明

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