Core/DBLayer: make use of return result of Connection::Open method and allow core to output all the errors in prepared statements instead of aborting on first error.

This commit is contained in:
Azazel
2011-04-07 15:30:38 +06:00
parent 770c8a950e
commit 4db04b63dd
9 changed files with 39 additions and 57 deletions

View File

@@ -68,6 +68,7 @@ class DatabaseWorkerPool
bool Open(const std::string& infoString, uint8 async_threads, uint8 synch_threads)
{
bool res = true;
m_connectionInfo = MySQLConnectionInfo(infoString);
sLog->outSQLDriver("Opening databasepool '%s'. Async threads: %u, synch threads: %u", m_connectionInfo.database.c_str(), async_threads, synch_threads);
@@ -77,7 +78,7 @@ class DatabaseWorkerPool
for (uint8 i = 0; i < async_threads; ++i)
{
T* t = new T(m_queue, m_connectionInfo);
t->Open();
res &= t->Open();
m_connections[IDX_ASYNC][i] = t;
++m_connectionCount[IDX_ASYNC];
}
@@ -87,13 +88,13 @@ class DatabaseWorkerPool
for (uint8 i = 0; i < synch_threads; ++i)
{
T* t = new T(m_connectionInfo);
t->Open();
res &= t->Open();
m_connections[IDX_SYNCH][i] = t;
++m_connectionCount[IDX_SYNCH];
}
sLog->outSQLDriver("Databasepool opened succesfuly. %u total connections running.", (m_connectionCount[IDX_SYNCH] + m_connectionCount[IDX_ASYNC]));
return true;
return res;
}
void Close()

View File

@@ -17,15 +17,11 @@
#include "CharacterDatabase.h"
bool CharacterDatabaseConnection::Open()
void CharacterDatabaseConnection::DoPrepareStatements()
{
if (!MySQLConnection::Open())
return false;
if (!m_reconnecting)
m_stmts.resize(MAX_CHARACTERDATABASE_STATEMENTS);
PREPARE_STATEMENT(CHAR_DEL_QUEST_POOL_SAVE, "DELETE FROM pool_quest_save WHERE pool_id = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_ADD_QUEST_POOL_SAVE, "INSERT INTO pool_quest_save (pool_id, quest_id) VALUES (?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_OLD_GUILD_EVENT_LOGS, "DELETE FROM guild_eventlog WHERE LogGuid > ?", CONNECTION_ASYNC)
@@ -299,9 +295,4 @@ bool CharacterDatabaseConnection::Open()
PREPARE_STATEMENT(CHAR_UPDATE_ARENA_TEAM_MEMBER, "UPDATE arena_team_member SET weekGames = ?, weekWins = ?, seasonGames = ?, seasonWins = ? WHERE arenaTeamId = ? AND guid = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_UPDATE_ARENA_TEAM_MEMBER_STATS, "REPLACE INTO character_arena_stats (guid, slot, personalRating, matchMakerRating) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_LOAD_PLAYER_ARENA_TEAMS, "SELECT arena_team_member.arenaTeamId FROM arena_team_member JOIN arena_team ON arena_team_member.arenaTeamId = arena_team.arenaTeamId WHERE guid = ?", CONNECTION_SYNCH);
for (PreparedStatementMap::const_iterator itr = m_queries.begin(); itr != m_queries.end(); ++itr)
PrepareStatement(itr->first, itr->second.first, itr->second.second);
return true;
}

View File

@@ -29,7 +29,7 @@ class CharacterDatabaseConnection : public MySQLConnection
CharacterDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) {}
//- Loads database type specific prepared statements
bool Open();
void DoPrepareStatements();
};
typedef DatabaseWorkerPool<CharacterDatabaseConnection> CharacterDatabaseWorkerPool;

View File

@@ -17,16 +17,11 @@
#include "LoginDatabase.h"
bool LoginDatabaseConnection::Open()
void LoginDatabaseConnection::DoPrepareStatements()
{
if (!MySQLConnection::Open())
return false;
if (!m_reconnecting)
m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS);
/* ################ LOAD PREPARED STATEMENTS HERE ################ */
PREPARE_STATEMENT(LOGIN_GET_REALMLIST, "SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE color <> 3 ORDER BY name", CONNECTION_SYNCH)
PREPARE_STATEMENT(LOGIN_SET_EXPIREDIPBANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC)
PREPARE_STATEMENT(LOGIN_SET_EXPIREDACCBANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC)
@@ -47,13 +42,4 @@ bool LoginDatabaseConnection::Open()
PREPARE_STATEMENT(LOGIN_SET_IP_NOT_BANNED, "DELETE FROM ip_banned WHERE ip = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(LOGIN_SET_ACCOUNT_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC)
PREPARE_STATEMENT(LOGIN_SET_ACCOUNT_NOT_BANNED, "UPDATE account_banned SET active = 0 WHERE id = ? AND active != 0", CONNECTION_ASYNC)
/* ############## END OF LOADING PREPARED STATEMENTS ############## */
for (PreparedStatementMap::const_iterator itr = m_queries.begin(); itr != m_queries.end(); ++itr)
{
PrepareStatement(itr->first, itr->second.first, itr->second.second);
}
return true;
}

View File

@@ -29,7 +29,7 @@ class LoginDatabaseConnection : public MySQLConnection
LoginDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) {}
//- Loads database type specific prepared statements
bool Open();
void DoPrepareStatements();
};
typedef DatabaseWorkerPool<LoginDatabaseConnection> LoginDatabaseWorkerPool;

View File

@@ -17,29 +17,15 @@
#include "WorldDatabase.h"
bool WorldDatabaseConnection::Open()
void WorldDatabaseConnection::DoPrepareStatements()
{
if (!MySQLConnection::Open())
return false;
if (!m_reconnecting)
m_stmts.resize(MAX_WORLDDATABASE_STATEMENTS);
/* ################ LOAD PREPARED STATEMENTS HERE ################ */
PREPARE_STATEMENT(WORLD_LOAD_QUEST_POOLS, "SELECT entry, pool_entry FROM pool_quest", CONNECTION_SYNCH)
PREPARE_STATEMENT(WORLD_DEL_CRELINKED_RESPAWN, "DELETE FROM linked_respawn WHERE guid = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(WORLD_REP_CRELINKED_RESPAWN, "REPLACE INTO linked_respawn (guid,linkedGuid) VALUES (?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(WORLD_LOAD_CRETEXT, "SELECT entry, groupid, id, text, type, language, probability, emote, duration, sound FROM creature_text", CONNECTION_SYNCH)
PREPARE_STATEMENT(WORLD_LOAD_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, target_type, target_param1, target_param2, target_param3, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link", CONNECTION_SYNCH)
PREPARE_STATEMENT(WORLD_LOAD_SMARTAI_WP, "SELECT entry, pointid, position_x, position_y, position_z FROM waypoints ORDER BY entry, pointid", CONNECTION_SYNCH)
/* ############## END OF LOADING PREPARED STATEMENTS ############## */
for (PreparedStatementMap::const_iterator itr = m_queries.begin(); itr != m_queries.end(); ++itr)
{
PrepareStatement(itr->first, itr->second.first, itr->second.second);
}
return true;
}

View File

@@ -29,7 +29,7 @@ class WorldDatabaseConnection : public MySQLConnection
WorldDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) {}
//- Loads database type specific prepared statements
bool Open();
void DoPrepareStatements();
};
typedef DatabaseWorkerPool<WorldDatabaseConnection> WorldDatabaseWorkerPool;

View File

@@ -34,6 +34,7 @@
MySQLConnection::MySQLConnection(MySQLConnectionInfo& connInfo) :
m_reconnecting(false),
m_prepareError(false),
m_queue(NULL),
m_worker(NULL),
m_Mysql(NULL),
@@ -44,6 +45,7 @@ m_connectionFlags(CONNECTION_SYNCH)
MySQLConnection::MySQLConnection(ACE_Activation_Queue* queue, MySQLConnectionInfo& connInfo) :
m_reconnecting(false),
m_prepareError(false),
m_queue(queue),
m_Mysql(NULL),
m_connectionInfo(connInfo),
@@ -137,7 +139,7 @@ bool MySQLConnection::Open()
// set connection properties to UTF8 to properly handle locales for different
// server configs - core sends data in UTF8, so MySQL must expect UTF8 too
mysql_set_character_set(m_Mysql, "utf8");
return true;
return PrepareStatements();
}
else
{
@@ -147,6 +149,14 @@ bool MySQLConnection::Open()
}
}
bool MySQLConnection::PrepareStatements()
{
DoPrepareStatements();
for (PreparedStatementMap::const_iterator itr = m_queries.begin(); itr != m_queries.end(); ++itr)
PrepareStatement(itr->first, itr->second.first, itr->second.second);
return !m_prepareError;
}
bool MySQLConnection::Execute(const char* sql)
{
if (!m_Mysql)
@@ -444,19 +454,23 @@ void MySQLConnection::PrepareStatement(uint32 index, const char* sql, Connection
{
sLog->outSQLDriver("[ERROR]: In mysql_stmt_init() id: %u, sql: \"%s\"", index, sql);
sLog->outSQLDriver("[ERROR]: %s", mysql_error(m_Mysql));
exit(1);
m_prepareError = true;
}
if (mysql_stmt_prepare(stmt, sql, static_cast<unsigned long>(strlen(sql))))
else
{
sLog->outSQLDriver("[ERROR]: In mysql_stmt_prepare() id: %u, sql: \"%s\"", index, sql);
sLog->outSQLDriver("[ERROR]: %s", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
exit(1);
if (mysql_stmt_prepare(stmt, sql, static_cast<unsigned long>(strlen(sql))))
{
sLog->outSQLDriver("[ERROR]: In mysql_stmt_prepare() id: %u, sql: \"%s\"", index, sql);
sLog->outSQLDriver("[ERROR]: %s", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
m_prepareError = true;
}
else
{
MySQLPreparedStatement* mStmt = new MySQLPreparedStatement(stmt);
m_stmts[index] = mStmt;
}
}
MySQLPreparedStatement* mStmt = new MySQLPreparedStatement(stmt);
m_stmts[index] = mStmt;
}
PreparedResultSet* MySQLConnection::Query(PreparedStatement* stmt)

View File

@@ -121,10 +121,14 @@ class MySQLConnection
MySQLPreparedStatement* GetPreparedStatement(uint32 index);
void PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags);
bool PrepareStatements();
virtual void DoPrepareStatements() = 0;
protected:
std::vector<MySQLPreparedStatement*> m_stmts; //! PreparedStatements storage
PreparedStatementMap m_queries; //! Query storage
bool m_reconnecting; //! Are we reconnecting?
bool m_prepareError; //! Was there any error while preparing statements?
private:
bool _HandleMySQLErrno(uint32 errNo);