www.pudn.com > evil¡¯s illusion Server Codes.rar > database.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; 
}