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

📄 postgresdatabase.cpp

📁 WOW 服务模拟端 支持2.4.3版本 来自开源的ASCENT 自己REPACK
💻 CPP
字号:

/* AscentEmu By SOI */

#include "DatabaseEnv.h"
#include "../CrashHandler.h"
#include "../NGLog.h"

#if defined(ENABLE_DATABASE_POSTGRES)

#include "PostgresDatabase.h"
#pragma comment(lib, "libpq.lib")

PostgresDatabase::~PostgresDatabase()
{
	delete [] Connections;
}

PostgresDatabase::PostgresDatabase() : Database()
{

}

void PostgresDatabase::_BeginTransaction(DatabaseConnection * conn)
{
	_SendQuery( conn, "BEGIN TRANSACTION", false );
}

void PostgresDatabase::_EndTransaction(DatabaseConnection * conn)
{
	_SendQuery( conn, "COMMIT TRANSACTION", false );
}

bool PostgresDatabase::Initialize(const char* Hostname, unsigned int port, const char* Username, const char* Password, const char* DatabaseName, uint32 ConnectionCount, uint32 BufferSize)
{
	uint32 i;
	PostgresDatabaseConnection * con;

	mHostname = string(Hostname);
	mConnectionCount = ConnectionCount;
	mUsername = string(Username);
	mPassword = string(Password);

	// Build the connection string
	stringstream ss;
	ss << "host = " << Hostname << " port = " << port << " ";
	ss << "user = '" << Username << "' ";
	if(strlen(Password) > 0)
		ss << "password = '" << Password << "' ";

	ss << "dbname = '" << DatabaseName << "'";
	mConnectString = ss.str();

	Log.Notice("PostgresDatabase", "Connecting to `%s`, database: `%s`...", Hostname, DatabaseName);
	Connections = new DatabaseConnection*[ConnectionCount];
	for( i = 0; i < ConnectionCount; ++i )
	{
		Connections[i] = new PostgresDatabaseConnection;
		con = static_cast<PostgresDatabaseConnection*>(Connections[i]);
		con->PgSql = PQconnectdb( mConnectString.c_str() );
		con->Result = NULL;
		if( con->PgSql == NULL )
		{
			Log.Error("PostgresDatabase", "Connection failed due to: `%s`", PQerrorMessage( con->PgSql ) );
			return false;
		}
	}

	Database::_Initialize();
	return true;
}

string PostgresDatabase::EscapeString(string Escape)
{
	char a2[16384] = {0};

	DatabaseConnection * con = GetFreeConnection();
	const char * ret;
	int err;
	if(PQescapeStringConn(static_cast<PostgresDatabaseConnection*>(con)->PgSql, a2, Escape.c_str(), (unsigned long)Escape.length(), &err) == 0)
		ret = Escape.c_str();
	else
		ret = a2;

	con->Busy.Release();
	return string(ret);
}

void PostgresDatabase::EscapeLongString(const char * str, uint32 len, stringstream& out)
{
	char a2[65536*3] = {0};

	DatabaseConnection * con = GetFreeConnection();
	const char * ret;
	int err;
	if(PQescapeStringConn(static_cast<PostgresDatabaseConnection*>(con)->PgSql, a2, str, (unsigned long)len, &err) == 0)
		ret = str;
	else
		ret = a2;

	out.write(a2, (std::streamsize)strlen(a2));
	con->Busy.Release();
}

string PostgresDatabase::EscapeString(const char * esc, DatabaseConnection * con)
{
	char a2[16384] = {0};
	const char * ret;
	int err;
	if(PQescapeStringConn(static_cast<PostgresDatabaseConnection*>(con)->PgSql, a2, (char*)esc, (unsigned long)strlen(esc), &err) == 0)
		ret = esc;
	else
		ret = a2;

	return string(ret);
}

void PostgresDatabase::Shutdown()
{
	// TODO
}

bool PostgresDatabase::_SendQuery(DatabaseConnection *con, const char* Sql, bool Self)
{
	PGresult * res = PQexec( static_cast<PostgresDatabaseConnection*>(con)->PgSql, Sql );
	if( res == NULL )
	{
		printf("Error: %s\n", PQerrorMessage( static_cast<PostgresDatabaseConnection*>(con)->PgSql ) );
		return false;
	}

	ExecStatusType result = PQresultStatus(res);
	if( result != PGRES_TUPLES_OK && result != PGRES_COMMAND_OK )
	{
		Log.Error("PostgreDatabase", "Query failed: %s", PQresultErrorMessage(res));
		PQclear( res );
		static_cast<PostgresDatabaseConnection*>(con)->Result = NULL;
		return false;
	}

	static_cast<PostgresDatabaseConnection*>(con)->Result = res;
	return true;
}

bool PostgresDatabase::_HandleError(PostgresDatabaseConnection * con, uint32 ErrorNumber)
{
	// Handle errors that should cause a reconnect to the Database.
	/*switch(ErrorNumber)
	{
	case 2006:  // Mysql server has gone away
	case 2008:  // Client ran out of memory
	case 2013:  // Lost connection to sql server during query
	case 2055:  // Lost connection to sql server - system error
		{
			// Let's instruct a reconnect to the db when we encounter these errors.
			return _Reconnect( con );
		}break;
	}*/

	return false;
}

PostgresQueryResult::PostgresQueryResult(PGresult* res, uint32 FieldCount, uint32 RowCount) : QueryResult(FieldCount, RowCount), mResult( res ), mRow(0)
{
	mCurrentRow = new Field[FieldCount];
}

PostgresQueryResult::~PostgresQueryResult()
{
	PQclear(mResult);
	delete [] mCurrentRow;
}

bool PostgresQueryResult::NextRow()
{
	char * pValue;
	uint32 i;

	if( mRow == mRowCount )
		return false;
	
	for( i = 0; i < mFieldCount; ++i )
	{
		pValue = PQgetvalue( mResult, mRow, i );
		if( pValue == NULL )
		{
			printf("NULL field in PostgresResult!!!\n");
			return false;
		}

		mCurrentRow[i].SetValue( pValue );
	}

	++mRow;
	return true;
}

QueryResult * PostgresDatabase::_StoreQueryResult(DatabaseConnection * con)
{
	PostgresQueryResult * res;
	PostgresDatabaseConnection * db = static_cast<PostgresDatabaseConnection*>(con);

	if( db->Result == NULL )
		return NULL;

	uint32 uRows = (uint32)PQntuples( db->Result );
	uint32 uFields = (uint32)PQnfields( db->Result );

	if( uRows == 0 || uFields == 0 )
	{
		PQclear( db->Result );
		db->Result = NULL;

		return NULL;
	}

	res = new PostgresQueryResult( db->Result, uFields, uRows );
	res->NextRow();

	db->Result = NULL;
	return res;
}

bool PostgresDatabase::_Reconnect(PostgresDatabaseConnection * conn)
{
	return false;
}

#endif

⌨️ 快捷键说明

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