summaryrefslogtreecommitdiff
path: root/utils/vmpi_private/mysql_wrapper/mysql_wrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/vmpi_private/mysql_wrapper/mysql_wrapper.cpp')
-rw-r--r--utils/vmpi_private/mysql_wrapper/mysql_wrapper.cpp398
1 files changed, 398 insertions, 0 deletions
diff --git a/utils/vmpi_private/mysql_wrapper/mysql_wrapper.cpp b/utils/vmpi_private/mysql_wrapper/mysql_wrapper.cpp
new file mode 100644
index 0000000..3b441e6
--- /dev/null
+++ b/utils/vmpi_private/mysql_wrapper/mysql_wrapper.cpp
@@ -0,0 +1,398 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+// mysql_wrapper.cpp : Defines the entry point for the DLL application.
+//
+#include "stdafx.h"
+
+extern "C"
+{
+ #include "mysql.h"
+};
+
+#include "imysqlwrapper.h"
+#include <stdio.h>
+
+
+static char* CopyString( const char *pStr )
+{
+ if ( !pStr )
+ {
+ pStr = "";
+ }
+
+ char *pRet = new char[ strlen( pStr ) + 1 ];
+ strcpy( pRet, pStr );
+ return pRet;
+}
+
+
+BOOL APIENTRY DllMain( HANDLE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ return TRUE;
+}
+
+
+class CCopiedRow
+{
+public:
+ ~CCopiedRow()
+ {
+ m_Columns.PurgeAndDeleteElements();
+ }
+
+ CUtlVector<char*> m_Columns;
+};
+
+
+class CMySQLCopiedRowSet : public IMySQLRowSet
+{
+public:
+ ~CMySQLCopiedRowSet()
+ {
+ m_Rows.PurgeAndDeleteElements();
+ m_ColumnNames.PurgeAndDeleteElements();
+ }
+
+ virtual void Release()
+ {
+ delete this;
+ }
+
+ virtual int NumFields()
+ {
+ return m_ColumnNames.Count();
+ }
+
+ virtual const char* GetFieldName( int iColumn )
+ {
+ return m_ColumnNames[iColumn];
+ }
+
+ virtual bool NextRow()
+ {
+ ++m_iCurRow;
+ return m_iCurRow < m_Rows.Count();
+ }
+
+ virtual bool SeekToFirstRow()
+ {
+ m_iCurRow = 0;
+ return m_iCurRow < m_Rows.Count();
+ }
+
+ virtual CColumnValue GetColumnValue( int iColumn )
+ {
+ return CColumnValue( this, iColumn );
+ }
+
+ virtual CColumnValue GetColumnValue( const char *pColumnName )
+ {
+ return CColumnValue( this, GetColumnIndex( pColumnName ) );
+ }
+
+ virtual const char* GetColumnValue_String( int iColumn )
+ {
+ if ( iColumn < 0 || iColumn >= m_ColumnNames.Count() )
+ return "<invalid column specified>";
+ else if ( m_iCurRow < 0 || m_iCurRow >= m_Rows.Count() )
+ return "<invalid row specified>";
+ else
+ return m_Rows[m_iCurRow]->m_Columns[iColumn];
+ }
+
+ virtual long GetColumnValue_Int( int iColumn )
+ {
+ return atoi( GetColumnValue_String( iColumn ) );
+ }
+
+ virtual int GetColumnIndex( const char *pColumnName )
+ {
+ for ( int i=0; i < m_ColumnNames.Count(); i++ )
+ {
+ if ( stricmp( m_ColumnNames[i], pColumnName ) == 0 )
+ return i;
+ }
+ return -1;
+ }
+
+
+public:
+ int m_iCurRow;
+ CUtlVector<CCopiedRow*> m_Rows;
+ CUtlVector<char*> m_ColumnNames;
+};
+
+
+// -------------------------------------------------------------------------------------------------------- //
+// CMySQL class.
+// -------------------------------------------------------------------------------------------------------- //
+
+class CMySQL : public IMySQL
+{
+public:
+ CMySQL();
+ virtual ~CMySQL();
+
+ virtual bool InitMySQL( const char *pDBName, const char *pHostName, const char *pUserName, const char *pPassword );
+ virtual void Release();
+ virtual int Execute( const char *pString );
+ virtual IMySQLRowSet* DuplicateRowSet();
+ virtual unsigned long InsertID();
+ virtual int NumFields();
+ virtual const char* GetFieldName( int iColumn );
+ virtual bool NextRow();
+ virtual bool SeekToFirstRow();
+ virtual CColumnValue GetColumnValue( int iColumn );
+ virtual CColumnValue GetColumnValue( const char *pColumnName );
+ virtual const char* GetColumnValue_String( int iColumn );
+ virtual long GetColumnValue_Int( int iColumn );
+ virtual int GetColumnIndex( const char *pColumnName );
+
+ // Cancels the storage of the rows from the latest query.
+ void CancelIteration();
+
+ virtual const char * GetLastError( void );
+
+
+public:
+
+ MYSQL *m_pSQL;
+ MYSQL_RES *m_pResult;
+ MYSQL_ROW m_Row;
+ CUtlVector<MYSQL_FIELD> m_Fields;
+
+ char m_szLastError[128];
+};
+
+
+EXPOSE_INTERFACE( CMySQL, IMySQL, MYSQL_WRAPPER_VERSION_NAME );
+
+
+// -------------------------------------------------------------------------------------------------------- //
+// CMySQL implementation.
+// -------------------------------------------------------------------------------------------------------- //
+
+CMySQL::CMySQL()
+{
+ m_pSQL = NULL;
+ m_pResult = NULL;
+ m_Row = NULL;
+}
+
+
+CMySQL::~CMySQL()
+{
+ CancelIteration();
+
+ if ( m_pSQL )
+ {
+ mysql_close( m_pSQL );
+ m_pSQL = NULL;
+ }
+}
+
+
+bool CMySQL::InitMySQL( const char *pDBName, const char *pHostName, const char *pUserName, const char *pPassword )
+{
+ MYSQL *pSQL = mysql_init( NULL );
+ if ( !pSQL )
+ return NULL;
+
+ if ( !mysql_real_connect( pSQL, pHostName, pUserName, pPassword, pDBName, 0, NULL, 0 ) )
+ {
+ Q_strncpy( m_szLastError, mysql_error( pSQL ), sizeof(m_szLastError) );
+
+ mysql_close( pSQL );
+ return false;
+ }
+
+ m_pSQL = pSQL;
+ return true;
+}
+
+
+void CMySQL::Release()
+{
+ delete this;
+}
+
+
+int CMySQL::Execute( const char *pString )
+{
+ CancelIteration();
+
+ int result = mysql_query( m_pSQL, pString );
+ if ( result == 0 )
+ {
+ // Is this a query with a result set?
+ m_pResult = mysql_store_result( m_pSQL );
+ if ( m_pResult )
+ {
+ // Store the field information.
+ int count = mysql_field_count( m_pSQL );
+ MYSQL_FIELD *pFields = mysql_fetch_fields( m_pResult );
+ m_Fields.CopyArray( pFields, count );
+ return 0;
+ }
+ else
+ {
+ // No result set. Was a set expected?
+ if ( mysql_field_count( m_pSQL ) != 0 )
+ return 1; // error! The query expected data but didn't get it.
+ }
+ }
+ else
+ {
+ const char *pError = mysql_error( m_pSQL );
+ pError = pError;
+ }
+
+ return result;
+}
+
+
+IMySQLRowSet* CMySQL::DuplicateRowSet()
+{
+ CMySQLCopiedRowSet *pSet = new CMySQLCopiedRowSet;
+
+ pSet->m_iCurRow = -1;
+
+ pSet->m_ColumnNames.SetSize( m_Fields.Count() );
+ for ( int i=0; i < m_Fields.Count(); i++ )
+ pSet->m_ColumnNames[i] = CopyString( m_Fields[i].name );
+
+ while ( NextRow() )
+ {
+ CCopiedRow *pRow = new CCopiedRow;
+ pSet->m_Rows.AddToTail( pRow );
+ pRow->m_Columns.SetSize( m_Fields.Count() );
+
+ for ( int i=0; i < m_Fields.Count(); i++ )
+ {
+ pRow->m_Columns[i] = CopyString( m_Row[i] );
+ }
+ }
+
+ return pSet;
+}
+
+
+unsigned long CMySQL::InsertID()
+{
+ return mysql_insert_id( m_pSQL );
+}
+
+
+int CMySQL::NumFields()
+{
+ return m_Fields.Count();
+}
+
+
+const char* CMySQL::GetFieldName( int iColumn )
+{
+ return m_Fields[iColumn].name;
+}
+
+
+bool CMySQL::NextRow()
+{
+ if ( !m_pResult )
+ return false;
+
+ m_Row = mysql_fetch_row( m_pResult );
+ if ( m_Row == 0 )
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+
+bool CMySQL::SeekToFirstRow()
+{
+ if ( !m_pResult )
+ return false;
+
+ mysql_data_seek( m_pResult, 0 );
+ return true;
+}
+
+
+CColumnValue CMySQL::GetColumnValue( int iColumn )
+{
+ return CColumnValue( this, iColumn );
+}
+
+
+CColumnValue CMySQL::GetColumnValue( const char *pColumnName )
+{
+ return CColumnValue( this, GetColumnIndex( pColumnName ) );
+}
+
+
+const char* CMySQL::GetColumnValue_String( int iColumn )
+{
+ if ( m_Row && iColumn >= 0 && iColumn < m_Fields.Count() && m_Row[iColumn] )
+ return m_Row[iColumn];
+ else
+ return "";
+}
+
+
+long CMySQL::GetColumnValue_Int( int iColumn )
+{
+ return atoi( GetColumnValue_String( iColumn ) );
+}
+
+
+int CMySQL::GetColumnIndex( const char *pColumnName )
+{
+ for ( int i=0; i < m_Fields.Count(); i++ )
+ {
+ if ( stricmp( pColumnName, m_Fields[i].name ) == 0 )
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+
+void CMySQL::CancelIteration()
+{
+ m_Fields.Purge();
+
+ if ( m_pResult )
+ {
+ mysql_free_result( m_pResult );
+ m_pResult = NULL;
+ }
+
+ m_Row = NULL;
+}
+
+const char *CMySQL::GetLastError( void )
+{
+ // Default to the last error if m_pSQL was not successfully initialized
+ const char *pszLastError = m_szLastError;
+
+ if ( m_pSQL )
+ {
+ pszLastError = mysql_error( m_pSQL );
+ }
+
+ return pszLastError;
+} \ No newline at end of file