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

📄 database.cpp

📁 此为传奇游戏源代码
💻 CPP
字号:


#include "stdafx.h"
#include "database.h"


/*
	Implement CDatabase methods
*/
CDatabase::CDatabase()
{
	m_hEnv		= NULL;
}


CDatabase::~CDatabase()
{
}


bool CDatabase::Init()
{
	if ( SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_hEnv ) != SQL_SUCCESS )
	   return false;

   if ( SQLSetEnvAttr( m_hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER ) != SQL_SUCCESS )
	   return false;

   return true;
}


void CDatabase::Uninit()
{
	if ( m_hEnv )
	{
		SQLFreeHandle( SQL_HANDLE_ENV, m_hEnv );
		m_hEnv = NULL;
	}
}


void CDatabase::EnumDSN( void (*pfnEnum)( char *pSrcName, char *pSrcDesc ) )
{
	int nResult;
	int nDirection = SQL_FETCH_FIRST;

	char szName[DB_MAXBUF], szDesc[DB_MAXBUF];
	int  nNameLen, nDescLen;

	while ( true )
	{
		nResult = SQLDataSourcesA( m_hEnv, 
								  nDirection, 
								  (byte *) szName, DB_MAXBUF, (short *) &nNameLen,
								  (byte *) szDesc, DB_MAXBUF, (short *) &nDescLen );

		if ( nResult == SQL_ERROR || nResult == SQL_NO_DATA )
			break;

		pfnEnum( szName, szDesc );

		nDirection = SQL_FETCH_NEXT;
	}
}


CConnection * CDatabase::CreateConnection( char *pDSN, char *pID, char *pPassword )
{
	CConnection *pConn = new CConnection;
	if ( pConn == NULL )
		return NULL;

	if ( pConn->Init( m_hEnv, pDSN, pID, pPassword ) == false )
	{
		delete pConn;
		return NULL;
	}

	return pConn;
}


void CDatabase::DestroyConnection( CConnection *pConn )
{
	pConn->Uninit();

	delete pConn;
}


/*
	Implement diagnostic record functions
*/
static void (*g_pfnRecord)( char *pState, int nErrCode, char *pDesc );


void CDatabase::SetDiagRec( void (*pfnRecord)( char *pState, int nErrCode, char *pDesc ) )
{
	g_pfnRecord = pfnRecord;
}


void CDatabase::UnsetDiagRec()
{
	g_pfnRecord = NULL;
}


void CDatabase::DiagRec( int nHandleType, SQLHANDLE hHandle )
{
	if ( g_pfnRecord == NULL )
		return;

	char szState[SQL_SQLSTATE_SIZE + 1];
	char szDesc[SQL_MAX_MESSAGE_LENGTH + 1];
	int  nDescLen;
	int  nNativeError;
	int  nResult;
	int  nRecCnt = 1;

	while ( true )
	{
		nResult = SQLGetDiagRecA( nHandleType, 
								 hHandle, 
								 nRecCnt++, 
								 (byte *) szState, 
								 (long *) &nNativeError, 
								 (byte *) szDesc, 
								 SQL_MAX_MESSAGE_LENGTH,
								 (short *) &nDescLen );
		
		if ( nResult == SQL_NO_DATA || nResult == SQL_ERROR || nResult == SQL_INVALID_HANDLE )
			break;

		g_pfnRecord( szState, nNativeError, szDesc );
	}
}


/*
	Implement CConnection methods
*/
CConnection::CConnection()
{
	m_hDBConn	= NULL;
}


CConnection::~CConnection()
{
}


bool CConnection::Init( SQLHENV hEnv, char *pDSN, char *pID, char *pPassword )
{
	int nResult;

	nResult = SQLAllocHandle( SQL_HANDLE_DBC, hEnv, &m_hDBConn );
	if ( nResult != SQL_SUCCESS )
	{
		CDatabase::DiagRec( SQL_HANDLE_ENV, hEnv );
		return false;
	}

	nResult = SQLConnectA( m_hDBConn, 
						  (byte *) pDSN, SQL_NTS, 
						  (byte *) pID, SQL_NTS, 
						  (byte *) pPassword, SQL_NTS );
	if ( nResult != SQL_SUCCESS )
	{
		CDatabase::DiagRec( SQL_HANDLE_DBC, m_hDBConn );

		if ( nResult != SQL_SUCCESS_WITH_INFO )
			return false;
	}

	return true;
}


void CConnection::Uninit()
{
/*	if ( m_hDBConn )
	{*/
		SQLDisconnect( m_hDBConn );
		SQLFreeHandle( SQL_HANDLE_DBC, m_hDBConn );
		m_hDBConn = NULL;
/*	}*/
}


CRecordset * CConnection::CreateRecordset()
{
	CRecordset *pRec = new CRecordset;
	if ( pRec == NULL )
		return NULL;

/*	if ( pRec->Init( m_hDBConn ) == false )
	{
		delete pRec;
		return NULL;
	}*/

	return pRec;
}


void CConnection::DestroyRecordset( CRecordset *pRec )
{
	pRec->Uninit();
	delete pRec;
}


/*
	Implement CRecordset methods
*/
CRecordset::CRecordset()
{
	m_hStmt		= NULL;

	m_nRowCount	= 0;
	m_nCols		= 0;

	m_pColInfo	= NULL;
	m_pColData	= NULL;
}


CRecordset::~CRecordset()
{
}


bool CRecordset::Init( SQLHDBC hDBConn )
{
	if ( SQLAllocHandle( SQL_HANDLE_STMT, hDBConn, &m_hStmt ) != SQL_SUCCESS )
	{
		CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );
		return false;
	}

	return true;
}


void CRecordset::Uninit()
{
	if ( m_pColInfo )
	{
		delete[] m_pColInfo;
		m_pColInfo = NULL;
	}
	
	if ( m_pColData )
	{
		delete[] m_pColData;
		m_pColData = NULL;
	}

	if ( m_hStmt )
	{
		SQLFreeHandle( SQL_HANDLE_STMT, m_hStmt );
		m_hStmt = NULL;
	}
}


bool CRecordset::Execute( char *pQuery )
{
	int nResult;
	int nCount;

	nResult = SQLExecDirectA( m_hStmt, (byte *) pQuery, SQL_NTS );
	if ( nResult != SQL_SUCCESS )
	{
		CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );

		if ( nResult != SQL_SUCCESS_WITH_INFO )
			return false;
	}

	m_nCols = 0;
	nResult = SQLNumResultCols( m_hStmt, (short *) &m_nCols );
	if ( nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO )
	{
		CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );
		return false;
	}
	
	// If cols is 0, the statement probably was a non-SELECT simply return.
	if ( m_nCols == 0 )
	{
		m_nRowCount = 0;
		SQLRowCount( m_hStmt, (long *) &m_nRowCount );
		return true;
	}

	m_pColInfo = new CColumnInfo[ m_nCols ];
	if ( m_pColInfo == NULL )
		return false;

	for ( nCount = 0; nCount < m_nCols; nCount++ )
	{
		nResult = SQLDescribeColA( m_hStmt, 
								  nCount + 1, 
								  (byte *) m_pColInfo[nCount].szColName, DB_MAXBUF,
								  (short *) &m_pColInfo[nCount].nColNameSize,
								  (short *) &m_pColInfo[nCount].nColType,
								  (ULONG *) &m_pColInfo[nCount].nColSize,
								  (short *) &m_pColInfo[nCount].nAllowDecimalDigit,
								  (short *) &m_pColInfo[nCount].nAllowNull );	
		
		if ( nResult != SQL_SUCCESS )
		{
			CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );

			if ( nResult != SQL_SUCCESS_WITH_INFO )
				return false;
		}
	}

	m_pColData = new CColumnData[ m_nCols ];
	if ( m_pColData == NULL )
		return false;

	for ( nCount = 0; nCount < m_nCols; nCount++ )
	{
		if ( m_pColData[nCount].AllocMemory( m_pColInfo[nCount].nColSize + 1 ) == false )
			return false;

		nResult = SQLBindCol( m_hStmt, 
							  nCount + 1, 
							  SQL_C_CHAR,
							  m_pColData[nCount].pData,
							  m_pColInfo[nCount].nColSize + 1,
							  (long *) &m_pColData[nCount].nDataSize );

		if ( nResult != SQL_SUCCESS )
		{
			CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );

			if ( nResult != SQL_SUCCESS_WITH_INFO )
				return false;
		}
	}

	return true;
}


bool CRecordset::Fetch()
{
	int nResult;

	nResult = SQLFetch( m_hStmt );
	if ( nResult != SQL_SUCCESS )
	{
		CDatabase::DiagRec( SQL_HANDLE_STMT, m_hStmt );

		if ( nResult != SQL_SUCCESS_WITH_INFO )
			return false;
	}

	return true;
}


int CRecordset::GetRowCount()
{
	return m_nRowCount;
}


int CRecordset::GetCols()
{
	return m_nCols;
}


char * CRecordset::Get( char *pColName )
{
	for ( int nCount = 0; nCount < m_nCols; nCount++ )
	{
		if ( stricmp( m_pColInfo[nCount].szColName, pColName ) == 0 )
			return m_pColData[nCount].pData;
	}

	return NULL;
}


char * CRecordset::Get( int nCol )
{
	if ( nCol < 0 || nCol >= m_nCols )
		return NULL;

	return m_pColData[ nCol ].pData;
}


CRecordset::CColumnInfo * CRecordset::GetColInfo( char *pColName )
{
	for ( int nCount = 0; nCount < m_nCols; nCount++ )
	{
		if ( stricmp( m_pColInfo[nCount].szColName, pColName ) == 0 )
			return &m_pColInfo[nCount];
	}

	return NULL;
}


CRecordset::CColumnInfo * CRecordset::GetColInfo( int nCol )
{
	if ( nCol < 0 || nCol >= m_nCols )
		return NULL;
	
	return &m_pColInfo[nCol];
}


/*
	Implement CRecordset::CColumnInfo methods
*/
CRecordset::CColumnInfo::CColumnInfo()
{
	nColNameSize		= 0;
	szColName[0]		= '\0';
	nColType			= 0;
	nColSize			= 0;
	nAllowDecimalDigit	= 0;
	nAllowNull			= 0;
}


CRecordset::CColumnInfo::~CColumnInfo()
{
}


/*
	Implement CRecordset::CColumnData methods
*/
CRecordset::CColumnData::CColumnData()
{
	pData		= NULL;
	nDataSize	= 0;
}


CRecordset::CColumnData::~CColumnData()
{
	if ( pData )
		delete[] pData;
}


bool CRecordset::CColumnData::AllocMemory( int nSize )
{
	pData = new char[ nSize ];
	if ( pData == NULL )
		return false;

	memset( pData, 0, nSize );

	return true;
}

⌨️ 快捷键说明

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