189 lines
5.0 KiB
C++
189 lines
5.0 KiB
C++
#include "database.h"
|
|
#include "../log.h"
|
|
|
|
// constructor
|
|
CDatabase::CDatabase( char* server , char* username, char* password, char* database, unsigned int port , MYSQL* mysql)
|
|
{
|
|
Server = server;
|
|
Username = username;
|
|
Password = password;
|
|
Database = database;
|
|
Port = port;
|
|
Mysql = mysql;
|
|
LastPing = time( NULL );
|
|
SQLMutex = PTHREAD_MUTEX_INITIALIZER;
|
|
mysql_init( Mysql );
|
|
}
|
|
|
|
// deconstructor
|
|
CDatabase::~CDatabase( )
|
|
{
|
|
}
|
|
|
|
// disconnect from mysql
|
|
void CDatabase::Disconnect( )
|
|
{
|
|
mysql_close( Mysql );
|
|
}
|
|
|
|
int CDatabase::Connect( )
|
|
{
|
|
Log( MSG_INFO, "Connecting to MySQL" );
|
|
if(!mysql_real_connect( Mysql, Server, Username, Password, Database,Port, NULL, 0 ))
|
|
{
|
|
Log( MSG_FATALERROR, "Error connecting to MySQL server: %s\n", mysql_error( Mysql ) );
|
|
return -1;
|
|
}
|
|
// Get timeout so we know when to ping - Drakia
|
|
MYSQL_RES *myresult = QStore("SELECT @@wait_timeout");
|
|
MYSQL_ROW row = mysql_fetch_row( myresult );
|
|
Timeout = atoi(row[0]) - 60; // Set the timeout to 1 minute before the connection will timeout
|
|
QFree( );
|
|
Log( MSG_INFO, "MySQL Ping Timeout: %d seconds", Timeout );
|
|
return 0;
|
|
}
|
|
|
|
// reconnect to mysql
|
|
int CDatabase::Reconnect( )
|
|
{
|
|
Log( MSG_INFO, "Reconnecting to Mysql" );
|
|
if(!mysql_real_connect( Mysql, Server, Username, Password, Database,Port, NULL, 0 ))
|
|
{
|
|
Log( MSG_FATALERROR, "Error reconnecting to MySQL server: %s\n", mysql_error( Mysql ) );
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// execute query
|
|
bool CDatabase::QExecute( const char *Format,... )
|
|
{
|
|
bool Qfail = true;
|
|
char query[80000];
|
|
va_list ap;
|
|
va_start( ap, Format );
|
|
vsprintf_s (query, Format, ap);
|
|
va_end ( ap );
|
|
Log( MSG_QUERY, query );
|
|
pthread_mutex_lock( &SQLMutex );
|
|
while(Qfail)
|
|
{
|
|
if(mysql_query( Mysql, query )!=0)
|
|
{
|
|
Log( MSG_FATALERROR, "Could not execute query: %s", mysql_error( Mysql ) );
|
|
if(Reconnect( )==-1)
|
|
{
|
|
Log( MSG_FATALERROR, "Could not execute query: %s", mysql_error( Mysql ) );
|
|
pthread_mutex_unlock( &SQLMutex );
|
|
return false;
|
|
}
|
|
else Qfail = false;
|
|
}
|
|
else Qfail = false;
|
|
}
|
|
pthread_mutex_unlock( &SQLMutex );
|
|
return true;
|
|
}
|
|
|
|
MYSQL_RES* CDatabase::QStore( const char *Format, ...)
|
|
{
|
|
bool Qfail = true;
|
|
char query[80000];
|
|
va_list ap;
|
|
va_start( ap, Format );
|
|
vsprintf_s( query, Format, ap );
|
|
va_end ( ap );
|
|
result = NULL;
|
|
Log( MSG_QUERY, query );
|
|
//Log( MSG_INFO, query );
|
|
//Log( MSG_INFO, "Locking pthread mutex" );
|
|
pthread_mutex_lock( &SQLMutex );
|
|
//Log( MSG_INFO, "Locked pthread mutex" );
|
|
while(Qfail)
|
|
{
|
|
if(mysql_query( Mysql, query )!=0)
|
|
{
|
|
Log( MSG_FATALERROR, "Could not execute query: %s", mysql_error( Mysql ) );
|
|
if(Reconnect( )==-1)
|
|
{
|
|
Log( MSG_FATALERROR, "Could not execute query: %s", mysql_error( Mysql ) );
|
|
pthread_mutex_unlock( &SQLMutex );
|
|
return NULL;
|
|
}
|
|
else Qfail = false;
|
|
}
|
|
else Qfail = false;
|
|
// Log( MSG_INFO, "mysql answer: %s", mysql_error( Mysql ) );
|
|
}
|
|
//Log( MSG_INFO, "reading mysql result" );
|
|
result = mysql_store_result( Mysql );
|
|
//Log( MSG_INFO, "returning mysql result" );
|
|
return result;
|
|
}
|
|
|
|
MYSQL_RES* CDatabase::QUse( const char *Format, ...)
|
|
{
|
|
bool Qfail = true;
|
|
char query[1024];
|
|
va_list ap;
|
|
va_start( ap, Format );
|
|
vsprintf_s( query, Format, ap );
|
|
va_end ( ap );
|
|
result = NULL;
|
|
Log( MSG_QUERY, query );
|
|
pthread_mutex_lock( &SQLMutex );
|
|
while(Qfail)
|
|
{
|
|
if(mysql_query( Mysql, query )!=0)
|
|
{
|
|
Log( MSG_FATALERROR, "Could not execute query: %s", mysql_error( Mysql ) );
|
|
if(Reconnect( )==-1)
|
|
{
|
|
Log( MSG_FATALERROR, "Could not execute query: %s", mysql_error( Mysql ) );
|
|
pthread_mutex_unlock( &SQLMutex );
|
|
return NULL;
|
|
}
|
|
else Qfail = false;
|
|
}
|
|
else Qfail = false;
|
|
}
|
|
result = mysql_use_result( Mysql );
|
|
return result;
|
|
}
|
|
|
|
bool CDatabase::DoSQL(const char *Format, ...) {
|
|
int retval;
|
|
char Buffer[1024];
|
|
va_list ap; va_start( ap, Format );
|
|
vsprintf_s( Buffer, Format, ap );
|
|
va_end ( ap );
|
|
retval = mysql_query( Mysql, Buffer );
|
|
if( retval!=0 ) Log( MSG_ERROR, "MySQL Query Error '%s'", mysql_error( Mysql ) );
|
|
return (retval==0);
|
|
}
|
|
|
|
void CDatabase::QFree( )
|
|
{
|
|
mysql_free_result( result );
|
|
pthread_mutex_unlock( &SQLMutex );
|
|
}
|
|
|
|
bool CDatabase::Ping( )
|
|
{
|
|
if ( time( NULL ) > ( LastPing + Timeout ) ) {
|
|
Log(MSG_INFO, "MySql Ping");
|
|
LastPing = time( NULL );
|
|
MYSQL_RES *res = QStore("SELECT @@wait_timeout");
|
|
if (res == NULL) {
|
|
Log( MSG_ERROR, "MySQL Ping Failed, Attempting reconnect" );
|
|
QFree( );
|
|
return !Reconnect( );
|
|
}
|
|
MYSQL_ROW row = mysql_fetch_row(res);
|
|
Timeout = atoi(row[0]) - 60;
|
|
QFree( );
|
|
Log( MSG_INFO, "MySql Pong, new Timeout: %d seconds", Timeout);
|
|
}
|
|
return true;
|
|
}
|