mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-07 17:29:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,543 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
//#include "misc.h"
|
||||
#include "isqlwrapper.h"
|
||||
#include "time.h"
|
||||
#include "sqlhelpers.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#pragma warning( disable : 4706 ) // Warning C4706: assignment within conditional expression
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: converts between a MySQL field type and our column types
|
||||
//-----------------------------------------------------------------------------
|
||||
EColumnType GetEColumnTypeFromESQLFieldType( ESQLFieldType eSQLFieldType )
|
||||
{
|
||||
switch( eSQLFieldType )
|
||||
{
|
||||
case FIELD_TYPE_DECIMAL:
|
||||
case FIELD_TYPE_TINY:
|
||||
case FIELD_TYPE_SHORT:
|
||||
case FIELD_TYPE_LONG:
|
||||
return SQL_INT;
|
||||
break;
|
||||
case FIELD_TYPE_FLOAT:
|
||||
case FIELD_TYPE_DOUBLE:
|
||||
return SQL_FLOAT;
|
||||
break;
|
||||
case FIELD_TYPE_LONGLONG:
|
||||
return SQL_UINT64;
|
||||
break;
|
||||
case FIELD_TYPE_NULL:
|
||||
case FIELD_TYPE_INT24:
|
||||
return SQL_NONE;
|
||||
break;
|
||||
case FIELD_TYPE_DATE:
|
||||
case FIELD_TYPE_TIMESTAMP:
|
||||
case FIELD_TYPE_TIME:
|
||||
case FIELD_TYPE_DATETIME:
|
||||
case FIELD_TYPE_YEAR:
|
||||
case FIELD_TYPE_NEWDATE:
|
||||
return SQL_TIME;
|
||||
break;
|
||||
case FIELD_TYPE_ENUM:
|
||||
case FIELD_TYPE_SET:
|
||||
case FIELD_TYPE_TINY_BLOB:
|
||||
case FIELD_TYPE_MEDIUM_BLOB:
|
||||
case FIELD_TYPE_LONG_BLOB:
|
||||
case FIELD_TYPE_BLOB:
|
||||
return SQL_NONE;
|
||||
break;
|
||||
case FIELD_TYPE_VAR_STRING:
|
||||
case FIELD_TYPE_STRING:
|
||||
return SQL_STRING;
|
||||
break;
|
||||
}
|
||||
return SQL_NONE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor.
|
||||
//-----------------------------------------------------------------------------
|
||||
CSQLColumn::CSQLColumn( const char *pchName, ESQLFieldType eSQLFieldType )
|
||||
{
|
||||
Assert( pchName );
|
||||
Q_strncpy( m_rgchName, pchName, sizeof( m_rgchName ) );
|
||||
m_ESQLFieldType = eSQLFieldType;
|
||||
m_EColumnType = GetEColumnTypeFromESQLFieldType( m_ESQLFieldType );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSQLTable::CSQLTable( const char *pchName )
|
||||
{
|
||||
Assert( pchName );
|
||||
Q_strncpy( m_rgchName, pchName, sizeof( m_rgchName ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: copy constructor (used by CUtlVector)
|
||||
//-----------------------------------------------------------------------------
|
||||
CSQLTable::CSQLTable( CSQLTable const &sqlTable )
|
||||
{
|
||||
Q_strncpy( m_rgchName, sqlTable.m_rgchName, sizeof( m_rgchName ) );
|
||||
for ( int iSQLColumn = 0; iSQLColumn < sqlTable.m_VecSQLColumn.Count(); iSQLColumn++ )
|
||||
{
|
||||
m_VecSQLColumn.AddToTail( CSQLColumn( sqlTable.m_VecSQLColumn[iSQLColumn].PchColumnName(),
|
||||
sqlTable.m_VecSQLColumn[iSQLColumn].GetESQLFieldType() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: add a new column to this data description
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSQLTable::AddColumn( const char *pchName, ESQLFieldType eSQLFieldType )
|
||||
{
|
||||
m_VecSQLColumn.AddToTail( CSQLColumn( pchName, eSQLFieldType ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ensure that all of our internal structures are consistent, and
|
||||
// account for all memory that we've allocated.
|
||||
// Input: validator - Our global validator object
|
||||
// pchName - Our name (typically a member var in our container)
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void CSQLTable::Validate( CValidator &validator, char *pchName )
|
||||
{
|
||||
validator.Push( "CSQLTable", this, pchName );
|
||||
|
||||
m_VecSQLColumn.Validate( validator, "m_VecSQLColumn" );
|
||||
|
||||
validator.Pop();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create the table descriptions from a data base
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSQLTableSet::Init( ISQLHelper *pSQLHelper )
|
||||
{
|
||||
m_VecSQLTable.RemoveAll();
|
||||
|
||||
MYSQL_RES *pMySQLRes = NULL;
|
||||
bool bRet = pSQLHelper->BInternalQuery( "show tables", &pMySQLRes );
|
||||
if ( !bRet || !pMySQLRes )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MYSQL_ROW row;
|
||||
while ( ( row = mysql_fetch_row( pMySQLRes ) ) )
|
||||
{
|
||||
CSQLTable sqlTable( row[0] );
|
||||
m_VecSQLTable.AddToTail( sqlTable );
|
||||
}
|
||||
mysql_free_result( pMySQLRes );
|
||||
|
||||
for ( int i = 0; i < m_VecSQLTable.Count(); i++ )
|
||||
{
|
||||
CSQLTable &sqlTable = m_VecSQLTable[i];
|
||||
|
||||
char szQuery[512];
|
||||
Q_snprintf( szQuery, sizeof(szQuery), "select * from %s limit 1", sqlTable.PchName() );
|
||||
MYSQL_RES *pMySQLRes = NULL;
|
||||
bool bRet = pSQLHelper->BInternalQuery( szQuery, &pMySQLRes );
|
||||
if ( !bRet || !pMySQLRes )
|
||||
{
|
||||
m_VecSQLTable.RemoveAll();
|
||||
return false;
|
||||
}
|
||||
|
||||
uint nFields = mysql_num_fields( pMySQLRes );
|
||||
Assert( nFields > 0 );
|
||||
MYSQL_FIELD *pFields = mysql_fetch_fields( pMySQLRes );
|
||||
for( uint i = 0; i < nFields; i++)
|
||||
{
|
||||
sqlTable.AddColumn( pFields[i].name, pFields[i].type );
|
||||
}
|
||||
|
||||
mysql_free_result( pMySQLRes );
|
||||
}
|
||||
|
||||
m_bInit = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to each table in the db
|
||||
//-----------------------------------------------------------------------------
|
||||
const ISQLTable *CSQLTableSet::PSQLTable( int iSQLTable ) const
|
||||
{
|
||||
return &m_VecSQLTable[iSQLTable];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ensure that all of our internal structures are consistent, and
|
||||
// account for all memory that we've allocated.
|
||||
// Input: validator - Our global validator object
|
||||
// pchName - Our name (typically a member var in our container)
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void CSQLTableSet::Validate( CValidator &validator, char *pchName )
|
||||
{
|
||||
validator.Push( "CSQLTableSet", this, pchName );
|
||||
|
||||
m_VecSQLTable.Validate( validator, "m_VecSQLTable" );
|
||||
for ( int i = 0; i < m_VecSQLTable.Count(); i++ )
|
||||
{
|
||||
m_VecSQLTable[i].Validate( validator, "m_VecSQLTable[i]" );
|
||||
}
|
||||
|
||||
validator.Pop();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSQLRow::CSQLRow( MYSQL_ROW *pMySQLRow, const ISQLTable *pSQLTableDescription, int cRowData )
|
||||
{
|
||||
Assert( pMySQLRow && pSQLTableDescription );
|
||||
for ( int iRowData = 0; iRowData < cRowData; iRowData++ )
|
||||
{
|
||||
struct SQLRowData_s sqlRowData;
|
||||
sqlRowData.eColumnType = pSQLTableDescription->GetEColumnType( iRowData );
|
||||
const CSQLTable *tableDesc = static_cast<const CSQLTable *>(pSQLTableDescription);
|
||||
switch ( tableDesc->GetESQLFieldType( iRowData ) )
|
||||
{
|
||||
case FIELD_TYPE_TINY:
|
||||
case FIELD_TYPE_DECIMAL:
|
||||
case FIELD_TYPE_SHORT:
|
||||
case FIELD_TYPE_LONG:
|
||||
sqlRowData.data.nData = atoi( ( *pMySQLRow ) [iRowData] );
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_FLOAT:
|
||||
case FIELD_TYPE_DOUBLE:
|
||||
sqlRowData.data.flData = atof( ( *pMySQLRow ) [iRowData] );
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_NULL:
|
||||
case FIELD_TYPE_INT24:
|
||||
memset( &sqlRowData.data, 0x0, sizeof( sqlRowData.data ) );
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_LONGLONG:
|
||||
sqlRowData.data.nData = atoi( ( *pMySQLRow ) [iRowData] );
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_TIMESTAMP:
|
||||
case FIELD_TYPE_DATETIME:
|
||||
{
|
||||
struct tm tm;
|
||||
char num[5];
|
||||
char szValue[64];
|
||||
Q_memset( &tm, 0x0, sizeof( tm ) );
|
||||
Q_strncpy( szValue, ( *pMySQLRow )[iRowData], sizeof( szValue ) );
|
||||
const char *str= szValue;
|
||||
num[0] =*str++; num[1] =*str++; num[2] =*str++; num[3] =*str++; num[4] = 0;
|
||||
tm.tm_year = strtol( num, 0, 10 ) - 1900;
|
||||
if (*str == '-') str++;
|
||||
num[0] = *str++; num[1] = *str++; num[2] = 0;
|
||||
tm.tm_mon = strtol( num, 0, 10 ) - 1;
|
||||
if (*str == '-') str++;
|
||||
num[0] = *str++; num[1] = *str++; num[2] = 0;
|
||||
tm.tm_mday = strtol( num, 0, 10 );
|
||||
num[0] = *str++; num[1] = *str++; num[2] = 0;
|
||||
tm.tm_hour = strtol( num, 0, 10 );
|
||||
if (*str == ':') str++;
|
||||
num[0] = *str++; num[1] = *str++; num[2] = 0;
|
||||
tm.tm_min = strtol( num, 0, 10 );
|
||||
if (*str == ':') str++;
|
||||
num[0] = *str++; num[1] = *str++; num[2] = 0;
|
||||
tm.tm_sec = strtol( num, 0, 10 );
|
||||
|
||||
sqlRowData.data.ulTime = _mktime64( &tm );
|
||||
}
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_TIME:
|
||||
case FIELD_TYPE_DATE:
|
||||
case FIELD_TYPE_YEAR:
|
||||
case FIELD_TYPE_NEWDATE:
|
||||
sqlRowData.data.ulTime = time( NULL ); // FIXME
|
||||
Assert( !"Not implemented" );
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_ENUM:
|
||||
case FIELD_TYPE_SET:
|
||||
case FIELD_TYPE_TINY_BLOB:
|
||||
case FIELD_TYPE_MEDIUM_BLOB:
|
||||
case FIELD_TYPE_LONG_BLOB:
|
||||
case FIELD_TYPE_BLOB:
|
||||
memset( &sqlRowData.data, 0x0, sizeof( sqlRowData.data ) );
|
||||
Assert( !"Not implemented" );
|
||||
break;
|
||||
|
||||
case FIELD_TYPE_VAR_STRING:
|
||||
case FIELD_TYPE_STRING:
|
||||
{
|
||||
int cchString = Q_strlen( ( char * )( *pMySQLRow )[iRowData] );
|
||||
char *pchNewString = new char[ cchString + 1 ];
|
||||
m_VecPchStoredStrings.AddToTail( pchNewString );
|
||||
Q_strncpy( pchNewString, ( char * )( *pMySQLRow )[iRowData], cchString + 1 );
|
||||
pchNewString[ cchString ] = 0;
|
||||
sqlRowData.data.pchData = pchNewString;
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_VecSQLRowData.AddToTail( sqlRowData );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSQLRow::~CSQLRow()
|
||||
{
|
||||
for ( int ipch = 0; ipch < m_VecPchStoredStrings.Count(); ipch++ )
|
||||
{
|
||||
delete m_VecPchStoredStrings[ipch];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: pointer to the char data
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSQLRow::PchData( int iRowData ) const
|
||||
{
|
||||
Assert( m_VecSQLRowData[iRowData].eColumnType == SQL_STRING );
|
||||
return m_VecSQLRowData[iRowData].data.pchData;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the int value of this column
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSQLRow::NData( int iRowData ) const
|
||||
{
|
||||
Assert( m_VecSQLRowData[iRowData].eColumnType == SQL_INT);
|
||||
return m_VecSQLRowData[iRowData].data.nData;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the uint64 value of this column
|
||||
//-----------------------------------------------------------------------------
|
||||
uint64 CSQLRow::UlData( int iRowData ) const
|
||||
{
|
||||
Assert( m_VecSQLRowData[iRowData].eColumnType == SQL_UINT64);
|
||||
return m_VecSQLRowData[iRowData].data.ulData;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the float value of this column
|
||||
//-----------------------------------------------------------------------------
|
||||
float CSQLRow::FlData( int iRowData ) const
|
||||
{
|
||||
Assert( m_VecSQLRowData[iRowData].eColumnType == SQL_FLOAT );
|
||||
return m_VecSQLRowData[iRowData].data.flData;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the time value of this column (time_t equivalent, seconds since midnight (00:00:00), January 1, 1970, coordinated universal time (UTC)
|
||||
// ignoring daylight savings
|
||||
//-----------------------------------------------------------------------------
|
||||
uint64 CSQLRow::UlTime( int iRowData ) const
|
||||
{
|
||||
Assert( m_VecSQLRowData[iRowData].eColumnType == SQL_TIME );
|
||||
return m_VecSQLRowData[iRowData].data.ulTime;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the boolean value of this column
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSQLRow::BData( int iRowData ) const
|
||||
{
|
||||
Assert( m_VecSQLRowData[iRowData].eColumnType == SQL_INT );
|
||||
return (m_VecSQLRowData[iRowData].data.nData == 1);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the data type contained in this column
|
||||
//-----------------------------------------------------------------------------
|
||||
EColumnType CSQLRow::GetEColumnType( int iRowData ) const
|
||||
{
|
||||
return m_VecSQLRowData[iRowData].eColumnType;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ensure that all of our internal structures are consistent, and
|
||||
// account for all memory that we've allocated.
|
||||
// Input: validator - Our global validator object
|
||||
// pchName - Our name (typically a member var in our container)
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void CSQLRow::Validate( CValidator &validator, char *pchName )
|
||||
{
|
||||
validator.Push( "CSQLRow", this, pchName );
|
||||
|
||||
m_VecSQLRowData.Validate( validator, "m_VecSQLRowData" );
|
||||
|
||||
m_VecPchStoredStrings.Validate( validator, "m_VecPchStoredStrings" );
|
||||
for ( int i = 0; i < m_VecPchStoredStrings.Count(); i++ )
|
||||
{
|
||||
validator.ClaimMemory( m_VecPchStoredStrings[i] );
|
||||
}
|
||||
|
||||
validator.Pop();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CResultSet::CResultSet()
|
||||
:m_SQLTableDescription( "Table" )
|
||||
{
|
||||
m_pSQLRow = NULL;
|
||||
m_MySQLRes = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: run a query on the database
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CResultSet::Query( const char *pchQuery, ISQLHelper *pSQLHelper )
|
||||
{
|
||||
m_SQLTableDescription.Reset();
|
||||
|
||||
m_pSQLRow = NULL;
|
||||
|
||||
bool bRet = pSQLHelper->BInternalQuery( pchQuery, &m_MySQLRes );
|
||||
if ( !bRet || !m_MySQLRes )
|
||||
{
|
||||
m_cSQLField = -1;
|
||||
m_cSQLRow = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cSQLField = mysql_num_fields( m_MySQLRes );
|
||||
m_cSQLRow = mysql_num_rows( m_MySQLRes );
|
||||
|
||||
MYSQL_FIELD *pMySQLField = mysql_fetch_fields( m_MySQLRes );
|
||||
for ( int iMySQLField = 0; iMySQLField < m_cSQLField; iMySQLField++ )
|
||||
{
|
||||
m_SQLTableDescription.AddColumn( pMySQLField[iMySQLField].name, pMySQLField[iMySQLField].type );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CResultSet::~CResultSet()
|
||||
{
|
||||
FreeResult();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: free any outstanding query
|
||||
//-----------------------------------------------------------------------------
|
||||
void CResultSet::FreeResult()
|
||||
{
|
||||
if ( m_MySQLRes )
|
||||
{
|
||||
mysql_free_result( m_MySQLRes );
|
||||
m_MySQLRes = NULL;
|
||||
}
|
||||
|
||||
if ( m_pSQLRow )
|
||||
{
|
||||
delete m_pSQLRow;
|
||||
m_pSQLRow = NULL;
|
||||
}
|
||||
|
||||
m_SQLTableDescription.Reset();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: number of rows in the result set
|
||||
//-----------------------------------------------------------------------------
|
||||
int CResultSet::GetCSQLRow() const
|
||||
{
|
||||
return m_cSQLRow;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get the new row from the result set
|
||||
//-----------------------------------------------------------------------------
|
||||
const ISQLRow *CResultSet::PSQLRowNextResult()
|
||||
{
|
||||
if ( m_pSQLRow )
|
||||
{
|
||||
delete m_pSQLRow;
|
||||
m_pSQLRow = NULL;
|
||||
}
|
||||
|
||||
MYSQL_ROW mySQLRow;
|
||||
if ( mySQLRow = mysql_fetch_row( m_MySQLRes ) )
|
||||
{
|
||||
m_pSQLRow = new CSQLRow( &mySQLRow, &m_SQLTableDescription, m_cSQLField );
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeResult(); // end of result set
|
||||
}
|
||||
|
||||
return m_pSQLRow;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ensure that all of our internal structures are consistent, and
|
||||
// account for all memory that we've allocated.
|
||||
// Input: validator - Our global validator object
|
||||
// pchName - Our name (typically a member var in our container)
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void CResultSet::Validate( CValidator &validator, char *pchName )
|
||||
{
|
||||
validator.Push( "CResultSet", this, pchName );
|
||||
|
||||
validator.ClaimMemory( m_MySQLRes );
|
||||
if ( m_pSQLRow )
|
||||
{
|
||||
validator.ClaimMemory( m_pSQLRow );
|
||||
m_pSQLRow->Validate( validator, "m_pSQLRow" );
|
||||
}
|
||||
|
||||
m_SQLTableDescription.Validate( validator, "m_SQLTableDescription" );
|
||||
|
||||
validator.Pop();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "utlvector.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <WinSock.H>
|
||||
#include "mysql.h"
|
||||
};
|
||||
#include "utlvector.h"
|
||||
|
||||
typedef enum_field_types ESQLFieldType;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: helper interface for running queries internal to this dll
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISQLHelper
|
||||
{
|
||||
public:
|
||||
// run a sql query on the db
|
||||
virtual bool BInternalQuery( const char *pchQueryString, MYSQL_RES **ppMySQLRes, bool bRecurse = true ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: represents the data about a single SQL column
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSQLColumn
|
||||
{
|
||||
public:
|
||||
CSQLColumn() { m_rgchName[0] = 0; }
|
||||
CSQLColumn( const char *pchName, ESQLFieldType eSQLFieldType );
|
||||
virtual const char *PchColumnName() const { return m_rgchName; };
|
||||
virtual EColumnType GetEColumnType() const { return m_EColumnType; };
|
||||
virtual ESQLFieldType GetESQLFieldType() const { return m_ESQLFieldType; };
|
||||
|
||||
private:
|
||||
char m_rgchName[64];
|
||||
EColumnType m_EColumnType;
|
||||
ESQLFieldType m_ESQLFieldType;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: encapsulates a table's description
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSQLTable : public ISQLTable
|
||||
{
|
||||
public:
|
||||
CSQLTable( const char *pchName );
|
||||
CSQLTable( CSQLTable const &CSQLTable ); // copy constructor
|
||||
void AddColumn( const char *pchName, ESQLFieldType ESQLFieldType );
|
||||
const char *PchName() const { return m_rgchName; };
|
||||
virtual int GetCSQLColumn() const { return m_VecSQLColumn.Count(); };
|
||||
virtual const char *PchColumnName( int iSQLColumn ) const { return m_VecSQLColumn[iSQLColumn].PchColumnName(); };
|
||||
virtual EColumnType GetEColumnType( int iSQLColumn ) const { return m_VecSQLColumn[iSQLColumn].GetEColumnType(); };
|
||||
virtual ESQLFieldType GetESQLFieldType( int iSQLColumn ) const { return m_VecSQLColumn[iSQLColumn].GetESQLFieldType(); };
|
||||
|
||||
void Reset() { m_VecSQLColumn.RemoveAll(); }
|
||||
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void Validate( CValidator &validator, char *pchName );
|
||||
#endif
|
||||
|
||||
private:
|
||||
char m_rgchName[64];
|
||||
CUtlVector<CSQLColumn> m_VecSQLColumn;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: encapsulates a db's worth of tables
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSQLTableSet : public ISQLTableSet
|
||||
{
|
||||
public:
|
||||
CSQLTableSet() { m_bInit = false; }
|
||||
bool Init( ISQLHelper *pISQLHelper );
|
||||
bool BInit() { return m_bInit; }
|
||||
virtual int GetCSQLTable() const { return m_VecSQLTable.Count(); };
|
||||
virtual const ISQLTable *PSQLTable( int iSQLTable ) const;
|
||||
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void Validate( CValidator &validator, char *pchName );
|
||||
#endif
|
||||
|
||||
private:
|
||||
static EColumnType EColumnTypeFromPchName( const char *pchName );
|
||||
CUtlVector<CSQLTable> m_VecSQLTable;
|
||||
bool m_bInit;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: describes a single row in a result set
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSQLRow : public ISQLRow
|
||||
{
|
||||
public:
|
||||
CSQLRow( MYSQL_ROW *pMySQLRow, const ISQLTable *pSQLTableDescription, int cSQLRowData );
|
||||
~CSQLRow();
|
||||
virtual int GetCSQLRowData() const { return m_VecSQLRowData.Count(); };
|
||||
virtual const char *PchData( int iSQLRowData ) const;
|
||||
virtual int NData( int iSQLRowData ) const;
|
||||
virtual uint64 UlData( int iSQLRowData ) const;
|
||||
virtual float FlData( int iSQLRowData ) const;
|
||||
virtual uint64 UlTime( int iSQLRowData ) const;
|
||||
virtual bool BData( int iSQLRowData ) const;
|
||||
virtual EColumnType GetEColumnType( int iSQLRowData ) const;
|
||||
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void Validate( CValidator &validator, char *pchName );
|
||||
#endif
|
||||
|
||||
private:
|
||||
struct SQLRowData_s
|
||||
{
|
||||
union
|
||||
{
|
||||
int nData;
|
||||
float flData;
|
||||
const char *pchData;
|
||||
uint64 ulTime;
|
||||
uint64 ulData;
|
||||
} data;
|
||||
EColumnType eColumnType;
|
||||
};
|
||||
|
||||
CUtlVector<struct SQLRowData_s> m_VecSQLRowData;
|
||||
CUtlVector<char *> m_VecPchStoredStrings;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: encapsulates a result set from a SQL query
|
||||
//-----------------------------------------------------------------------------
|
||||
class CResultSet : public IResultSet
|
||||
{
|
||||
public:
|
||||
CResultSet();
|
||||
~CResultSet();
|
||||
bool Query( const char *pchQuery, ISQLHelper *pISQLHelper );
|
||||
virtual int GetCSQLRow() const;
|
||||
virtual const ISQLRow *PSQLRowNextResult();
|
||||
void FreeResult();
|
||||
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void Validate( CValidator &validator, char *pchName );
|
||||
#endif
|
||||
|
||||
private:
|
||||
MYSQL_RES *m_MySQLRes;
|
||||
CSQLRow *m_pSQLRow;
|
||||
CSQLTable m_SQLTableDescription;
|
||||
int m_cSQLField;
|
||||
int m_cSQLRow;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,453 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
//#include "misc.h"
|
||||
//#include "stdafx.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
////// MySQL API includes
|
||||
#include <WinSock.H>
|
||||
#include "mysql.h"
|
||||
#include "errmsg.h"
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
#include "isqlwrapper.h"
|
||||
#include "sqlhelpers.h"
|
||||
#include "interface.h"
|
||||
#include "utllinkedlist.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
///////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Main dll entry point
|
||||
// Input: hModule - our module handle
|
||||
// dwReason - reason we were called
|
||||
// lpReserved - bad idea that some Windows developer had some day that
|
||||
// we're stuck with
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef _WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD dwReason,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch ( dwReason )
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#elif _LINUX
|
||||
void __attribute__ ((constructor)) app_init(void);
|
||||
void app_init(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
class CSQLWrapper : public ISQLWrapper, public ISQLHelper
|
||||
{
|
||||
public:
|
||||
CSQLWrapper();
|
||||
~CSQLWrapper ();
|
||||
|
||||
// ISQLWrapper
|
||||
virtual void Init( const char *pchDB, const char *pchHost, const char *pchUsername, const char *pchPassword );
|
||||
virtual bool BInsert( const char *pchQueryString );
|
||||
virtual const ISQLTableSet *PSQLTableSetDescription();
|
||||
virtual IResultSet *PResultSetQuery( const char *pchQueryString );
|
||||
virtual void FreeResult();
|
||||
|
||||
// ISQLHelper
|
||||
virtual bool BInternalQuery( const char *pchQueryString, MYSQL_RES **ppMySQLRes, bool bRecurse /* = true */ );
|
||||
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void Validate( CValidator &validator, char *pchName ); // Validate our internal structures
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool BConnect();
|
||||
void Disconnect();
|
||||
bool _Query( const char *pchQueryString, MYSQL_RES **result );
|
||||
|
||||
char *m_pchDB;
|
||||
char *m_pchHost;
|
||||
char *m_pchUsername;
|
||||
char *m_pchPassword;
|
||||
bool m_bConnected;
|
||||
|
||||
MYSQL m_MySQL;
|
||||
CSQLTableSet m_SQLTableSet;
|
||||
CResultSet m_ResultSet;
|
||||
bool m_bInQuery;
|
||||
};
|
||||
|
||||
|
||||
class CSQLWrapperFactory : public ISQLWrapperFactory
|
||||
{
|
||||
public:
|
||||
CSQLWrapperFactory() {};
|
||||
~CSQLWrapperFactory() {};
|
||||
|
||||
virtual ISQLWrapper *Create( const char *pchDB, const char *pchHost, const char *pchUsername, const char *pchPassword );
|
||||
virtual void Free( ISQLWrapper *pWrapper );
|
||||
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void Validate( CValidator &validator, char *pchName ); // Validate our internal structures
|
||||
#endif
|
||||
|
||||
private:
|
||||
CUtlFixedLinkedList<CSQLWrapper> m_ListSQLWrapper; // use a fixed in memory data struct so we can return pointers to the interfaces
|
||||
};
|
||||
|
||||
CSQLWrapperFactory g_SQLWrapperFactory;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CSQLWrapperFactory, ISQLWrapperFactory, INTERFACEVERSION_ISQLWRAPPER, g_SQLWrapperFactory );
|
||||
|
||||
#if 0
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ensure that all of our internal structures are consistent, and
|
||||
// account for all memory that we've allocated.
|
||||
// Input: validator - Our global validator object
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDLLValidate : public IValidate
|
||||
{
|
||||
public:
|
||||
virtual void Validate( CValidator & validator )
|
||||
{
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
g_SQLWrapperFactory.Validate( validator, "g_SQLWrapperFactory" );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
CDLLValidate g_DLLValidate;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CDLLValidate, IValidate, INTERFACEVERSION_IVALIDATE, g_DLLValidate );
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create a SQLWrapper interface to use
|
||||
// Input: pchDB - database name to connect to
|
||||
// pchHost - host to connect to
|
||||
// pchUsername - username to connect as
|
||||
// pchPassword - password to use
|
||||
// Output: a pointer to a sql wrapper interface
|
||||
//-----------------------------------------------------------------------------
|
||||
ISQLWrapper *CSQLWrapperFactory::Create( const char *pchDB, const char *pchHost, const char *pchUsername, const char *pchPassword )
|
||||
{
|
||||
int iSQLWrapper = m_ListSQLWrapper.AddToTail();
|
||||
CSQLWrapper &sqlWrapper = m_ListSQLWrapper[iSQLWrapper];
|
||||
sqlWrapper.Init( pchDB, pchHost, pchUsername, pchPassword );
|
||||
return &sqlWrapper;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Free a previously allocated sql interface
|
||||
// Input: pWrapper - interface that was alloced
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSQLWrapperFactory::Free( ISQLWrapper *pSQLWrapper )
|
||||
{
|
||||
FOR_EACH_LL( m_ListSQLWrapper, iSQLWrapper )
|
||||
{
|
||||
if ( &m_ListSQLWrapper[iSQLWrapper] == ((CSQLWrapper *)pSQLWrapper) )
|
||||
{
|
||||
m_ListSQLWrapper.Remove(iSQLWrapper);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert( iSQLWrapper != m_ListSQLWrapper.InvalidIndex() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ensure that all of our internal structures are consistent, and
|
||||
// account for all memory that we've allocated.
|
||||
// Input: validator - Our global validator object
|
||||
// pchName - Our name (typically a member var in our container)
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void CSQLWrapperFactory::Validate( CValidator &validator, char *pchName )
|
||||
{
|
||||
validator.Push( "CSQLWrapperFactory", this, pchName );
|
||||
|
||||
m_ListSQLWrapper.Validate( validator, "m_ListSQLWrapper" );
|
||||
|
||||
FOR_EACH_LL( m_ListSQLWrapper, iListSQLWrapper )
|
||||
{
|
||||
m_ListSQLWrapper[ iListSQLWrapper ].Validate( validator, "m_ListSQLWrapper[ iListSQLWrapper ]" );
|
||||
}
|
||||
|
||||
validator.Pop();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SAFE_DELETE( pointer ) if ( pointer != NULL ) { delete pointer; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor.
|
||||
//-----------------------------------------------------------------------------
|
||||
CSQLWrapper::CSQLWrapper()
|
||||
{
|
||||
m_pchDB = NULL;
|
||||
m_pchHost = NULL;
|
||||
m_pchUsername = NULL;
|
||||
m_pchPassword = NULL;
|
||||
m_bConnected = false;
|
||||
m_bInQuery = false;
|
||||
|
||||
mysql_init( &m_MySQL );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor.
|
||||
//-----------------------------------------------------------------------------
|
||||
CSQLWrapper::~CSQLWrapper()
|
||||
{
|
||||
FreeResult();
|
||||
mysql_close( &m_MySQL );
|
||||
m_bConnected = false;
|
||||
|
||||
SAFE_DELETE(m_pchDB);
|
||||
SAFE_DELETE(m_pchHost);
|
||||
SAFE_DELETE(m_pchUsername);
|
||||
SAFE_DELETE(m_pchPassword);
|
||||
}
|
||||
|
||||
// helper macro to alloc and copy a string to a member var
|
||||
// BUGBUG Alfred: Make this a Q_function
|
||||
#define COPY_STRING( dst, src ) \
|
||||
dst = new char[Q_strlen(src) + 1]; \
|
||||
Assert( dst ); \
|
||||
Q_strncpy( dst, src, Q_strlen(src) + 1); \
|
||||
dst[ Q_strlen(src) ] = 0;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initializer. Sets up connection params but DOESN'T actually do the connection
|
||||
// Input: pchDB - database name to connect to
|
||||
// pchHost - host to connect to
|
||||
// pchUsername - username to connect as
|
||||
// pchPassword - password to use
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSQLWrapper::Init( const char *pchDB, const char *pchHost, const char *pchUsername, const char *pchPassword )
|
||||
{
|
||||
COPY_STRING( m_pchDB, pchDB );
|
||||
COPY_STRING( m_pchHost, pchHost );
|
||||
COPY_STRING( m_pchUsername, pchUsername );
|
||||
COPY_STRING( m_pchPassword, pchPassword );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Connects to a MySQL server.
|
||||
// Output: true if connect works, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSQLWrapper::BConnect()
|
||||
{
|
||||
m_bInQuery = false;
|
||||
|
||||
MYSQL *pMYSQL = mysql_real_connect( &m_MySQL, m_pchHost, m_pchUsername, m_pchPassword, m_pchDB, 0, NULL, 0);
|
||||
if ( !pMYSQL || pMYSQL != &m_MySQL ) // on success we get our SQL pointer back
|
||||
{
|
||||
DevMsg( "Failed to connect to DB server (%s)\n", mysql_error(&m_MySQL) );
|
||||
return false;
|
||||
}
|
||||
m_bConnected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Disconnects from a mysql if you are already connected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSQLWrapper::Disconnect()
|
||||
{
|
||||
mysql_close( &m_MySQL );
|
||||
mysql_init( &m_MySQL );
|
||||
m_bConnected = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: run a query on the db with retries
|
||||
// Input: pchQueryString - query string to run
|
||||
// ppMySQLRes - mysql result set to set
|
||||
// bRecurse - if true allow this function to call itself again (to rety the query)
|
||||
// Output: true if query succeeds, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSQLWrapper::BInternalQuery( const char *pchQueryString, MYSQL_RES **ppMySQLRes, bool bRecurse )
|
||||
{
|
||||
*ppMySQLRes = NULL;
|
||||
if ( !m_pchDB || !m_pchHost || !m_pchUsername || !m_pchPassword || !ppMySQLRes )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !m_bConnected )
|
||||
{
|
||||
BConnect(); // need to reconnect
|
||||
}
|
||||
|
||||
bool bRet = _Query( pchQueryString, ppMySQLRes );
|
||||
if ( !bRet && !m_bConnected && bRecurse ) // hmmm, got hung up when running the query
|
||||
{
|
||||
bRet = BInternalQuery( pchQueryString, ppMySQLRes, false ); // run the query again now we reconnected
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Actually runs a query on the server
|
||||
// Input: pchQueryString - query string to run
|
||||
// result - mysql result set to set
|
||||
// Output: true if query succeeds, false otherwise, result it set on success
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSQLWrapper::_Query( const char *pchQueryString, MYSQL_RES **ppMySQLRes )
|
||||
{
|
||||
*ppMySQLRes = NULL;
|
||||
int iResult = mysql_real_query( &m_MySQL, pchQueryString, Q_strlen(pchQueryString) );
|
||||
if ( iResult != 0 )
|
||||
{
|
||||
int iErrNo = mysql_errno(&m_MySQL);
|
||||
if ( iErrNo == CR_COMMANDS_OUT_OF_SYNC ) // I hate this return code, you just need to hang up and try again
|
||||
{
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
else if ( iErrNo == CR_SERVER_LOST || iErrNo == CR_SERVER_GONE_ERROR )
|
||||
{
|
||||
m_bConnected = false;
|
||||
return false;
|
||||
}
|
||||
else if ( iErrNo != 0 )
|
||||
{
|
||||
DevMsg( "CSQLWrapper::_Query Generic SQL query error: %s\n", mysql_error( &m_MySQL ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mysql_field_count( &m_MySQL ) > 0 ) // if there are results clear them from the connection
|
||||
{
|
||||
*ppMySQLRes = mysql_store_result( &m_MySQL );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Runs a insert style query on the db (i.e no return set), opens the connection if it isn't currently
|
||||
// Input: pchQueryString - query string to run
|
||||
// Output: true if query succeeds, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSQLWrapper::BInsert( const char *pchQueryString )
|
||||
{
|
||||
if ( m_bInQuery )
|
||||
{
|
||||
Assert( !m_bInQuery );
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bInQuery = true;
|
||||
MYSQL_RES *pMySQLRes = NULL;
|
||||
bool bRet = BInternalQuery( pchQueryString, &pMySQLRes, true );
|
||||
if ( bRet && pMySQLRes )
|
||||
{
|
||||
mysql_free_result( pMySQLRes );
|
||||
}
|
||||
m_bInQuery = false;
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to the table descriptions for this DB
|
||||
// Output: table description pointer
|
||||
//-----------------------------------------------------------------------------
|
||||
const ISQLTableSet *CSQLWrapper::PSQLTableSetDescription()
|
||||
{
|
||||
if ( m_bInQuery )
|
||||
{
|
||||
Assert( !m_bInQuery );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_bInQuery = true;
|
||||
if ( !m_SQLTableSet.Init( this ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_bInQuery = false;
|
||||
return &m_SQLTableSet;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Runs a select style query on the db (i.e a return set), opens the connection if it isn't currently
|
||||
// Input: pchQueryString - query string to run
|
||||
// Output: returns a pointer to the result set (NULL on failure)
|
||||
//-----------------------------------------------------------------------------
|
||||
IResultSet *CSQLWrapper::PResultSetQuery( const char *pchQueryString )
|
||||
{
|
||||
if ( m_bInQuery )
|
||||
{
|
||||
Assert( !m_bInQuery );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool bRet = m_ResultSet.Query( pchQueryString, this );
|
||||
if ( !bRet )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
m_bInQuery = true;
|
||||
return &m_ResultSet;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Free's any currently running result set
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSQLWrapper::FreeResult()
|
||||
{
|
||||
m_bInQuery = false;
|
||||
m_ResultSet.FreeResult();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ensure that all of our internal structures are consistent, and
|
||||
// account for all memory that we've allocated.
|
||||
// Input: validator - Our global validator object
|
||||
// pchName - Our name (typically a member var in our container)
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void CSQLWrapper::Validate( CValidator &validator, char *pchName )
|
||||
{
|
||||
validator.Push( "CSQLWrapper", this, pchName );
|
||||
|
||||
validator.ClaimMemory( m_pchDB );
|
||||
validator.ClaimMemory( m_pchHost );
|
||||
validator.ClaimMemory( m_pchUsername );
|
||||
validator.ClaimMemory( m_pchPassword );
|
||||
|
||||
m_SQLTableSet.Validate( validator, "m_SQLTableSet" );
|
||||
m_ResultSet.Validate( validator, "m_ResultSet" );
|
||||
|
||||
validator.Pop();
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,200 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="SQLWrapper"
|
||||
ProjectGUID="{D66A7F7E-CD38-45CC-951D-E22E5DED6585}"
|
||||
SccProjectName="Perforce Project"
|
||||
SccAuxPath=""
|
||||
SccLocalPath=".."
|
||||
SccProvider="MSSCCI:Perforce SCM"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\..\bin\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\common;..\..\public;..\..;..\..\public\tier0;..\..\public\tier1;..\vmpi_private\mysql\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="TRUE"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="if exist ..\..\..\game\bin\sqlwrapper.dll attrib -r ..\..\..\game\bin\sqlwrapper.dll
|
||||
copy "$(TargetDir)"sqlwrapper.dll ..\..\..\game\bin\sqlwrapper.dll
|
||||
if exist ..\..\..\game\bin\sqlwrapper.pdb attrib -r ..\..\..\game\bin\sqlwrapper.pdb
|
||||
copy "$(TargetDir)"sqlwrapper.pdb ..\..\..\game\bin
|
||||
if exist ..\..\..\src\lib\common\sqlwrapper.lib attrib -r ..\..\..\src\lib\common\sqlwrapper.lib
|
||||
copy "$(TargetDir)"sqlwrapper.lib ..\..\..\src\lib\common\
|
||||
|
||||
"
|
||||
Outputs="..\..\..\game\bin\"$(TargetName)".dll"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="mswsock.lib winmm.lib ws2_32.lib libmySQL.lib tier0.lib tier1.lib vstdlib.lib"
|
||||
OutputFile="$(OutDir)/sqlwrapper.dll"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""../../common/$(IntDir)";../../lib/public;../vmpi_private/mysql/lib/opt"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/sqlwrapper.pdb"
|
||||
SubSystem="0"
|
||||
ImportLibrary="$(OutDir)/sqlwrapper.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\..\bin\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OptimizeForProcessor="3"
|
||||
AdditionalIncludeDirectories="..\..\common;..\..\public;..\..;..\..\public\tier0;..\..\public\tier1;..\vmpi_private\mysql\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="FALSE"
|
||||
EnableFunctionLevelLinking="FALSE"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="TRUE"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="if exist ..\..\..\game\bin\sqlwrapper.dll attrib -r ..\..\..\game\bin\sqlwrapper.dll
|
||||
copy "$(TargetDir)"sqlwrapper.dll ..\..\..\game\bin\sqlwrapper.dll
|
||||
|
||||
if exist ..\..\..\game\bin\sqlwrapper.pdb attrib -r ..\..\..\game\bin\sqlwrapper.pdb
|
||||
copy "$(TargetDir)"sqlwrapper.pdb ..\..\..\game\bin\sqlwrapper.pdb
|
||||
|
||||
if exist ..\..\..\src\lib\common\sqlwrapper.lib attrib -r ..\..\..\src\lib\common\sqlwrapper.lib
|
||||
copy "$(TargetDir)"sqlwrapper.lib ..\..\..\src\lib\common\sqlwrapper.lib
|
||||
|
||||
"
|
||||
Outputs="..\..\..\game\bin\"$(TargetName)".dll"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="mswsock.lib winmm.lib ws2_32.lib libmySQL.lib tier0.lib tier1.lib vstdlib.lib"
|
||||
OutputFile="$(OutDir)/sqlwrapper.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""../../common/$(IntDir)";../../lib/public;../vmpi_private/mysql/lib/opt"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/sqlwrapper.pdb"
|
||||
SubSystem="0"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(OutDir)/sqlwrapper.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\tier1\interface.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\tier0\memoverride.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sqlhelpers.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sqlwrapper.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath="..\..\public\tier1\interface.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\isqlwrapper.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vmpi_private\mysql\include\mysql.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sqlhelpers.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
Reference in New Issue
Block a user