예제 #1
0
bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount)
{
    if (!m_Mysql)
        return false;

    uint32 index = stmt->m_index;
    {
        MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index);
        ASSERT(m_mStmt);            // Can only be null if preparation failed, server side error or bad query
        m_mStmt->m_stmt = stmt;     // Cross reference them for debug output
        stmt->m_stmt = m_mStmt;     // TODO: Cleaner way

        stmt->BindParameters();

        MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
        MYSQL_BIND* msql_BIND = m_mStmt->GetBind();

        uint32 _s = 0;
        if (sLogMgr->IsLogEnabled(SQLDRIVER_LOG))
            _s = getMSTime();

        if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLogMgr->WriteLn(SQLDRIVER_LOG, "SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return _Query(stmt, pResult, pRowCount, pFieldCount);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (mysql_stmt_execute(msql_STMT))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLogMgr->WriteLn(SQLDRIVER_LOG, "SQL(p): %s\n [ERROR]: [%u] %s",
                m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return _Query(stmt, pResult, pRowCount, pFieldCount);      // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (sLogMgr->IsLogEnabled(SQLDRIVER_LOG))
            sLogMgr->WriteLn(SQLDRIVER_LOG, "[%u ms] SQL(p): %s", getMSTimeDiff(_s, getMSTime()), m_mStmt->getQueryString(m_queries[index].first).c_str());

        m_mStmt->ClearParameters();

        *pResult = mysql_stmt_result_metadata(msql_STMT);
        *pRowCount = mysql_stmt_num_rows(msql_STMT);
        *pFieldCount = mysql_stmt_field_count(msql_STMT);

        return true;
    }
}
예제 #2
0
bool MySQLConnection::Execute(PreparedStatement* stmt)
{
    if (!m_Mysql)
        return false;

    uint32 index = stmt->m_index;
    {
        MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index);
        ASSERT(m_mStmt);            // Can only be null if preparation failed, server side error or bad query
        m_mStmt->m_stmt = stmt;     // Cross reference them for debug output
        stmt->m_stmt = m_mStmt;     // TODO: Cleaner way

        stmt->BindParameters();

        MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
        MYSQL_BIND* msql_BIND = m_mStmt->GetBind();

        uint32 _s = 0;
        if (sLog->GetSQLDriverQueryLogging())
            _s = getMSTime();

        if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("[ERROR]: PreparedStatement (id: %u, database: `%s`) error binding params:  [%u] %s",
                index, m_connectionInfo.database.c_str(), lErrno, mysql_stmt_error(msql_STMT));
            
            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled succesfuly (ie reconnection)
                return Execute(stmt);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (mysql_stmt_execute(msql_STMT))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("[ERROR]: PreparedStatement (id: %u, database: `%s`) error executing:  [%u] %s",
                index, m_connectionInfo.database.c_str(), lErrno, mysql_stmt_error(msql_STMT));
            
            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled succesfuly (ie reconnection)
                return Execute(stmt);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }
        
        if (sLog->GetSQLDriverQueryLogging())
            sLog->outSQLDriver("[%u ms] Prepared SQL: %u on database `%s`",
                getMSTimeDiff(_s, getMSTime()), index, m_connectionInfo.database.c_str());
 
        m_mStmt->ClearParameters();
        return true;
    }
}
예제 #3
0
bool MySQLConnection::Execute(PreparedStatement* stmt)
{
    if (!m_Mysql)
        return false;

    uint32 index = stmt->m_index;
    {
        MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index);
        /*ASSERT*/(m_mStmt);            // Can only be null if preparation failed, server side error or bad query
        m_mStmt->m_stmt = stmt;     // Cross reference them for debug output
        stmt->m_stmt = m_mStmt;     // TODO: Cleaner way

        stmt->BindParameters();

        MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
        MYSQL_BIND* msql_BIND = m_mStmt->GetBind();

        uint32 _s = 0;
        if (sLog->GetSQLDriverQueryLogging())
            _s = getMSTime();

        if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(stmt);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (mysql_stmt_execute(msql_STMT))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(stmt);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (sLog->GetSQLDriverQueryLogging())
            sLog->outSQLDriver("[%u ms] SQL(p): %s", getMSTimeDiff(_s, getMSTime()), m_mStmt->getQueryString(m_queries[index].first).c_str());

        m_mStmt->ClearParameters();
        return true;
    }
}
예제 #4
0
bool MySqlConnection::_Query(PreparedStmt* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount)
{
	if (!m_Mysql)
		return false;

	uint32 index = stmt->m_stmtIndex;
	{
		MySqlPreparedStmt* pStmt = GetPreparedStatement(index);
		pStmt->m_pPrepareStmt = stmt;     // Cross reference them for debug output
		stmt->m_pStmt = pStmt;     /// @todo Cleaner way

		stmt->bindParameters();

		MYSQL_STMT* msql_STMT = pStmt->GetMySqlStmt();
		MYSQL_BIND* msql_BIND = pStmt->GetBind();

		if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
		{
			uint32 lErrno = mysql_errno(m_Mysql);
			ERROR_LOG("SQL(p): %s\n [ERROR]: [%u] %s\n", pStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

			if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
				return _Query(stmt, pResult, pRowCount, pFieldCount);       // Try again

			pStmt->clearParameters();
			return false;
		}

		TRACE_LOG("Exe SQL(p): %s\n\n", pStmt->getQueryString(m_queries[index].first).c_str());
		if (mysql_stmt_execute(msql_STMT))
		{
			uint32 lErrno = mysql_errno(m_Mysql);
			ERROR_LOG("SQL(p): %s\n [ERROR]: [%u] %s\n",
                      pStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

			if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
				return _Query(stmt, pResult, pRowCount, pFieldCount);      // Try again

			pStmt->clearParameters();
			return false;
		}
		
		pStmt->clearParameters();

		*pResult = mysql_stmt_result_metadata(msql_STMT);
		*pRowCount = mysql_stmt_num_rows(msql_STMT);
		*pFieldCount = mysql_stmt_field_count(msql_STMT);

		return true;
	}
}
예제 #5
0
bool MySQLConnection::Execute(PreparedStatement* stmt)
{
    if (!m_Mysql)
        return false;

    uint32 index = stmt->m_index;
    {
        MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index);
        ASSERT(m_mStmt);            // Can only be null if preparation failed, server side error or bad query
        m_mStmt->m_stmt = stmt;     // Cross reference them for debug output
        stmt->m_stmt = m_mStmt;     /// @todo Cleaner way

        stmt->BindParameters();

        MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
        MYSQL_BIND* msql_BIND = m_mStmt->GetBind();

       boost::timer _s;

        if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            _LOG_ERROR(LOG_FILTER_SQL, "SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(stmt);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        if (mysql_stmt_execute(msql_STMT))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            _LOG_ERROR(LOG_FILTER_SQL, "SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(stmt);       // Try again

            m_mStmt->ClearParameters();
            return false;
        }

        _LOG_DEBUG(LOG_FILTER_SQL, "[%u ms] SQL(p): %s",(uint32)_s.elapsed(), m_mStmt->getQueryString(m_queries[index].first).c_str());

        m_mStmt->ClearParameters();
        return true;
    }
}
예제 #6
0
bool MySQLConnection::Execute(const char* sql)
{
    if (!m_Mysql)
        return false;

    {
        uint32 _s = 0;
        if (sLog->GetSQLDriverQueryLogging())
            _s = getMSTime();

        if (mysql_query(m_Mysql, sql))
        {
            uint32 lErrno = mysql_errno(m_Mysql);

            sLog->outSQLDriver("SQL: %s", sql);
            sLog->outSQLDriver("ERROR: [%u] %s", lErrno, mysql_error(m_Mysql));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(sql);       // Try again

            return false;
        }
        else if (sLog->GetSQLDriverQueryLogging())
        {
            sLog->outSQLDriver("[%u ms] SQL: %s", getMSTimeDiff(_s, getMSTime()), sql);
        }
    }

    return true;
}
예제 #7
0
bool MySQLConnection::Execute(char const* sql)
{
    if (!m_Mysql)
        return false;

    {
        uint32 _s = getMSTime();

        if (mysql_query(m_Mysql, sql))
        {
            uint32 lErrno = mysql_errno(m_Mysql);

            TC_LOG_INFO("sql.sql", "SQL: %s", sql);
            TC_LOG_ERROR("sql.sql", "[%u] %s", lErrno, mysql_error(m_Mysql));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(sql);       // Try again

            return false;
        }
        else
            TC_LOG_DEBUG("sql.sql", "[%u ms] SQL: %s", getMSTimeDiff(_s, getMSTime()), sql);
    }

    return true;
}
예제 #8
0
bool MySQLConnection::Execute(const char* sql)
{
    if (!m_Mysql)
        return false;

    {
        uint32 _s = 0;
        if (sLogMgr->IsLogEnabled(SQLDRIVER_LOG))
            _s = getMSTime();

        if (mysql_query(m_Mysql, sql))
        {
            uint32 lErrno = mysql_errno(m_Mysql);

            sLogMgr->WriteLn(SQLDRIVER_LOG, "SQL: %s", sql);
            sLogMgr->WriteLn(SQLDRIVER_LOG, "ERROR: [%u] %s", lErrno, mysql_error(m_Mysql));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(sql);       // Try again

            return false;
        }
        else if (sLogMgr->IsLogEnabled(SQLDRIVER_LOG))
        {
            sLogMgr->WriteLn(SQLDRIVER_LOG, "[%u ms] SQL: %s", getMSTimeDiff(_s, getMSTime()), sql);
        }
    }

    return true;
}
예제 #9
0
bool MySqlConnection::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount)
{
	if (!m_Mysql)
		return false;
	{
		if (mysql_query(m_Mysql, sql))
		{
			uint32 lErrno = mysql_errno(m_Mysql);
			TRACE_LOG("SQL: %s\n", sql);
			ERROR_LOG("[%u] %s\n", lErrno, mysql_error(m_Mysql));

			if (_HandleMySQLErrno(lErrno))      // If it returns true, an error was handled successfully (i.e. reconnection)
				return _Query(sql, pResult, pFields, pRowCount, pFieldCount);    // We try again

			return false;
		}

		*pResult = mysql_store_result(m_Mysql);
		*pRowCount = mysql_affected_rows(m_Mysql);
		*pFieldCount = mysql_field_count(m_Mysql);
	}

	if (!*pResult )
		return false;

	if (!*pRowCount)
	{
		mysql_free_result(*pResult);
		return false;
	}

	*pFields = mysql_fetch_fields(*pResult);

	return true;
}
bool MySQLConnection::Execute(const char* sql)
{
    if (!m_Mysql)
        return false;

    {
        uint32 _s = getMSTime();

        if (mysql_query(m_Mysql, sql))
        {
            uint32 lErrno = mysql_errno(m_Mysql);

            sLog->outInfo(LOG_FILTER_SQL, "SQL: %s", sql);
            sLog->outError(LOG_FILTER_SQL, "[%u] %s", lErrno, mysql_error(m_Mysql));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(sql);       // Try again

            return false;
        }
        else
            sLog->outDebug(LOG_FILTER_SQL, "[%u ms] SQL: %s", getMSTimeDiff(_s, getMSTime()), sql);
    }

    return true;
}
예제 #11
0
bool MySQLConnection::Execute(const char* sql)
{
    if (!m_Mysql)
        return false;

    {
		boost::timer _s;
        

        if (mysql_query(m_Mysql, sql))
        {
            uint32 lErrno = mysql_errno(m_Mysql);

            _LOG_INFO(LOG_FILTER_SQL, "SQL: %s", sql);
            _LOG_ERROR(LOG_FILTER_SQL, "[%u] %s", lErrno, mysql_error(m_Mysql));

            if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
                return Execute(sql);       // Try again

            return false;
        }
        else
            _LOG_DEBUG(LOG_FILTER_SQL, "[%u ms] SQL: %s",(uint32) _s.elapsed(), sql);
    }

    return true;
}
bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
{
    switch (errNo)
    {
        case CR_SERVER_GONE_ERROR:
        case CR_SERVER_LOST:
        case CR_INVALID_CONN_HANDLE:
        case CR_SERVER_LOST_EXTENDED:
        {
            m_reconnecting = true;
            uint64 oldThreadId = mysql_thread_id(GetHandle());
            mysql_close(GetHandle());
            if (this->Open())                           // Don't remove 'this' pointer unless you want to skip loading all prepared statements....
            {
                sLog->outInfo(LOG_FILTER_SQL, "Connection to the MySQL server is active.");
                if (oldThreadId != mysql_thread_id(GetHandle()))
                    sLog->outInfo(LOG_FILTER_SQL, "Successfully reconnected to %s @%s:%s (%s).",
                        m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
                            (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");

                m_reconnecting = false;
                return true;
            }

            uint32 lErrno = mysql_errno(GetHandle());   // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
            ACE_OS::sleep(3);                           // Sleep 3 seconds
            return _HandleMySQLErrno(lErrno);           // Call self (recursive)
        }

        case ER_LOCK_DEADLOCK:
            return false;    // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction
        // Query related errors - skip query
        case ER_WRONG_VALUE_COUNT:
        case ER_DUP_ENTRY:
            return false;

        // Outdated table or database structure - terminate core
        case ER_BAD_FIELD_ERROR:
        case ER_NO_SUCH_TABLE:
            sLog->outError(LOG_FILTER_SQL, "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
            ACE_OS::sleep(10);
            std::abort();
            return false;
        case ER_PARSE_ERROR:
            sLog->outError(LOG_FILTER_SQL, "Error while parsing SQL. Core fix required.");
            ACE_OS::sleep(10);
            std::abort();
            return false;
        default:
            sLog->outError(LOG_FILTER_SQL, "Unhandled MySQL errno %u. Unexpected behaviour possible.", errNo);
            return false;
    }
}
예제 #13
0
bool MySqlConnection::Execute(PreparedStmt* stmt)
{
    if (!m_Mysql)
		return false;

	uint32 index = stmt->m_stmtIndex;
	MySqlPreparedStmt* pStmt = GetPreparedStatement(index);
	pStmt->m_pPrepareStmt = stmt;
	stmt->m_pStmt = pStmt;
	stmt->bindParameters();	
	MYSQL_STMT* pMySqlStmt = pStmt->GetMySqlStmt();
	MYSQL_BIND* pMySqlBind = pStmt->GetBind();
	if (mysql_stmt_bind_param(pMySqlStmt, pMySqlBind))
	{
		uint32 lErrno = mysql_errno(m_Mysql);	
		ERROR_LOG("MySqlConnection::execute mysql_stmt_bind_param failed %u\n", lErrno);
		if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
            return Execute(stmt);       // Try again
			
		pStmt->clearParameters();
		return false;
	}
	TRACE_LOG("Exe SQL(p): %s\n\n", pStmt->getQueryString(m_queries[index].first).c_str());
	if (mysql_stmt_execute(pMySqlStmt))
	{
		uint32 lErrno = mysql_errno(m_Mysql);
		ERROR_LOG("MySqlConnection::execute mysql_stmt_bind_param failed %u\n", lErrno);
		if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
            return Execute(stmt);       // Try again
				
		pStmt->clearParameters();
		return false;
	}

	return true;
}
예제 #14
0
bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
{
    switch (errNo)
    {
        case 2006:  // "MySQL server has gone away"
        case 2013:  // "Lost connection to MySQL server during query"
        case 2048:  // "Invalid connection handle"
        case 2055:  // "Lost connection to MySQL server at '%s', system error: %d"
        {
            m_reconnecting = true;
            uint64 oldThreadId = mysql_thread_id(GetHandle());
            mysql_close(GetHandle());
            if (this->Open())                           // Don't remove 'this' pointer unless you want to skip loading all prepared statements....
            {
                sLog->outSQLDriver("Connection to the MySQL server is active.");
                if (oldThreadId != mysql_thread_id(GetHandle()))
                    sLog->outSQLDriver("Successfully reconnected to %s @%s:%s (%s).",
                        m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
                            (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");

                m_reconnecting = false;
                return true;
            }

            uint32 lErrno = mysql_errno(GetHandle());   // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
            ACE_OS::sleep(3);                           // Sleep 3 seconds
            return _HandleMySQLErrno(lErrno);           // Call self (recursive)
        }

        case 1213:      // "Deadlock found when trying to get lock; try restarting transaction"
            return false;    // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction
        // Query related errors - skip query
        case 1058:      // "Column count doesn't match value count"
        case 1062:      // "Duplicate entry '%s' for key '%d'"
            return false;

        // Outdated table or database structure - terminate core
        case 1054:      // "Unknown column '%s' in '%s'"
        case 1146:      // "Table '%s' doesn't exist"
            WPFatal(!errNo, "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
            return false;

        default:
            sLog->outSQLDriver("Unhandled MySQL errno %u. Unexpected behaviour possible.", errNo);
            return false;
    }
}
예제 #15
0
bool MySqlConnection::Execute(const char* sql)
{
	if (!m_Mysql)
		return false;

	if (mysql_query(m_Mysql, sql))
	{
		uint32 lErrno = mysql_errno(m_Mysql);
		ERROR_LOG("execute sql:%s failed return [%u] %s\n", sql, lErrno, mysql_error(m_Mysql));
		if (_HandleMySQLErrno(lErrno))  // If it returns true, an error was handled successfully (i.e. reconnection)
			return Execute(sql);       // Try again

		return false;
	}
	
	return true;
}
예제 #16
0
bool MySQLConnection::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount)
{
    if (!m_Mysql)
        return false;

    {
        uint32 _s = 0;
        if (sLog->GetSQLDriverQueryLogging())
            _s = getMSTime();

        if (mysql_query(m_Mysql, sql))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outSQLDriver("SQL: %s", sql);
            sLog->outSQLDriver("ERROR: [%u] %s", lErrno, mysql_error(m_Mysql));

            if (_HandleMySQLErrno(lErrno))      // If it returns true, an error was handled successfully (i.e. reconnection)	
                return _Query(sql, pResult, pFields, pRowCount, pFieldCount);    // We try again 

            return false;
        }
        else if (sLog->GetSQLDriverQueryLogging())
        {
            sLog->outSQLDriver("[%u ms] SQL: %s", getMSTimeDiff(_s,getMSTime()), sql);
        }

        *pResult = mysql_store_result(m_Mysql);
        *pRowCount = mysql_affected_rows(m_Mysql);
        *pFieldCount = mysql_field_count(m_Mysql);
    }

    if (!*pResult )
        return false;

    if (!*pRowCount)
    {
        mysql_free_result(*pResult);
        return false;
    }

    *pFields = mysql_fetch_fields(*pResult);

    return true;
}
bool MySQLConnection::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount)
{
    if (!m_Mysql)
        return false;

    {
        uint32 _s = getMSTime();

        if (mysql_query(m_Mysql, sql))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            sLog->outInfo(LOG_FILTER_SQL, "SQL: %s", sql);
            sLog->outError(LOG_FILTER_SQL, "[%u] %s", lErrno, mysql_error(m_Mysql));

            if (lErrno == ER_BAD_FIELD_ERROR || lErrno == ER_NO_SUCH_TABLE || lErrno == ER_PARSE_ERROR)
                sLog->outError(LOG_FILTER_SQL, "TrinityCore TRANSFERT ERROR %u : query : %s", lErrno, sql);

            if (_HandleMySQLErrno(lErrno))      // If it returns true, an error was handled successfully (i.e. reconnection)
                return _Query(sql, pResult, pFields, pRowCount, pFieldCount);    // We try again

            return false;
        }
        else
            sLog->outDebug(LOG_FILTER_SQL, "[%u ms] SQL: %s", getMSTimeDiff(_s, getMSTime()), sql);

        *pResult = mysql_store_result(m_Mysql);
        *pRowCount = mysql_affected_rows(m_Mysql);
        *pFieldCount = mysql_field_count(m_Mysql);
    }

    if (!*pResult )
        return false;

    if (!*pRowCount)
    {
        mysql_free_result(*pResult);
        return false;
    }

    *pFields = mysql_fetch_fields(*pResult);

    return true;
}
예제 #18
0
bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
{
    switch (errNo)
    {
    case 2006:  // "MySQL server has gone away"
    case 2013:  // "Lost connection to MySQL server during query"
    case 2048:  // "Invalid connection handle"
    case 2055:  // "Lost connection to MySQL server at '%s', system error: %d"
    {
        m_reconnecting = true;
        uint64 oldThreadId = mysql_thread_id(GetHandle());
        mysql_close(GetHandle());
        if (this->Open())                           // Don't remove 'this' pointer unless you want to skip loading all prepared statements....
        {
            sLog->outSQLDriver("Die Verbindung zum MySQL-Server aktiv ist.");
            if (oldThreadId != mysql_thread_id(GetHandle()))
                sLog->outSQLDriver("Online %s @%s:%s (%s).",
                                   m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
                                   (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");

            m_reconnecting = false;
            return true;
        }

        uint32 lErrno = mysql_errno(GetHandle());   // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
        ACE_OS::sleep(3);                           // Sleep 3 seconds
        return _HandleMySQLErrno(lErrno);           // Call self (recursive)
    }

    case 1213:      // "Deadlock found when trying to get lock; try restarting transaction"
        return false;    // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction
    // Query related errors - skip query
    case 1058:      // "Column count doesn't match value count"
    case 1062:      // "Duplicate entry '%s' for key '%d'"
    case 1054:      // "Unknown column '%s' in 'order clause'"
        return false;

    default:
        sLog->outSQLDriver("Unbehandelte MySQL Err %u. Unerwarteter Fehler.", errNo);
        return false;
    }
}
예제 #19
0
bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
{
    sLog->outDebug("%s", __FUNCTION__);

    switch (errNo)
    {
        case 2006:  // "MySQL server has gone away"
        case 2013:  // "Lost connection to MySQL server during query"
        case 2048:  // "Invalid connection handle"
        case 2055:  // "Lost connection to MySQL server at '%s', system error: %d"
        {
            m_reconnecting = true;
            uint64 oldThreadId = mysql_thread_id(GetHandle());
            mysql_close(GetHandle());
            if (this->Open())                           // Don't remove 'this' pointer unless you want to skip loading all prepared statements....
            {
                sLog->outSQLDriver("Connection to the MySQL server is active.");
                if (oldThreadId != mysql_thread_id(GetHandle()))
                    sLog->outSQLDriver("Succesfuly reconnected to %s @%s:%s (%s).", 
                        m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
                            (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");

                m_reconnecting = false;
                return true;
            }

            uint32 lErrno = mysql_errno(GetHandle());   // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
            ACE_OS::sleep(3);                           // Sleep 3 seconds
            return _HandleMySQLErrno(lErrno);           // Call self (recursive)
        }

        // Query related errors - skip query
        case 1058:      // "Column count doesn't match value count"
        case 1062:      // "Duplicate entry '%s' for key '%d'"
        case 1054:      // "Unknown column '%s' in 'order clause'"
            return false;

        default:
            sLog->outSQLDriver("Unhandled MySQL errno %u. Unexpected behaviour possible.", errNo);
            return false;
    }
}
예제 #20
0
bool MySQLConnection::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount)
{
    if (!m_Mysql)
        return false;

    {
       boost::timer _s;

        if (mysql_query(m_Mysql, sql))
        {
            uint32 lErrno = mysql_errno(m_Mysql);
            _LOG_INFO(LOG_FILTER_SQL, "SQL: %s", sql);
            _LOG_ERROR(LOG_FILTER_SQL, "[%u] %s", lErrno, mysql_error(m_Mysql));

            if (_HandleMySQLErrno(lErrno))      // If it returns true, an error was handled successfully (i.e. reconnection)
                return _Query(sql, pResult, pFields, pRowCount, pFieldCount);    // We try again

            return false;
        }
        else
            _LOG_DEBUG(LOG_FILTER_SQL, "[%u ms] SQL: %s",(uint32)_s.elapsed(), sql);

        *pResult = mysql_store_result(m_Mysql);
        *pRowCount = mysql_affected_rows(m_Mysql);
        *pFieldCount = mysql_field_count(m_Mysql);
    }

    if (!*pResult )
        return false;

    if (!*pRowCount)
    {
        mysql_free_result(*pResult);
        return false;
    }

    *pFields = mysql_fetch_fields(*pResult);

    return true;
}
예제 #21
0
bool MySQLConnection::_HandleMySQLErrno(uint32 errNo, uint8 attempts /*= 5*/)
{
    switch (errNo)
    {
        case CR_SERVER_GONE_ERROR:
        case CR_SERVER_LOST:
#ifdef CR_INVALID_CONN_HANDLE
        case CR_INVALID_CONN_HANDLE:
#endif
        case CR_SERVER_LOST_EXTENDED:
        {
            if (m_Mysql)
            {
                TC_LOG_ERROR("sql.sql", "Lost the connection to the MySQL server!");

                mysql_close(GetHandle());
                m_Mysql = nullptr;
            }

            /*no break*/
        }
        case CR_CONN_HOST_ERROR:
        {
            TC_LOG_INFO("sql.sql", "Attempting to reconnect to the MySQL server...");

            m_reconnecting = true;

            uint32 const lErrno = Open();
            if (!lErrno)
            {
                // Don't remove 'this' pointer unless you want to skip loading all prepared statements...
                if (!this->PrepareStatements())
                {
                    TC_LOG_FATAL("sql.sql", "Could not re-prepare statements!");
                    std::this_thread::sleep_for(std::chrono::seconds(10));
                    std::abort();
                }

                TC_LOG_INFO("sql.sql", "Successfully reconnected to %s @%s:%s (%s).",
                    m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
                        (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");

                m_reconnecting = false;
                return true;
            }

            if ((--attempts) == 0)
            {
                // Shut down the server when the mysql server isn't
                // reachable for some time
                TC_LOG_FATAL("sql.sql", "Failed to reconnect to the MySQL server, "
                             "terminating the server to prevent data corruption!");

                // We could also initiate a shutdown through using std::raise(SIGTERM)
                std::this_thread::sleep_for(std::chrono::seconds(10));
                std::abort();
            }
            else
            {
                // It's possible this attempted reconnect throws 2006 at us.
                // To prevent crazy recursive calls, sleep here.
                std::this_thread::sleep_for(std::chrono::seconds(3)); // Sleep 3 seconds
                return _HandleMySQLErrno(lErrno, attempts); // Call self (recursive)
            }
        }

        case ER_LOCK_DEADLOCK:
            return false;    // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction
        // Query related errors - skip query
        case ER_WRONG_VALUE_COUNT:
        case ER_DUP_ENTRY:
            return false;

        // Outdated table or database structure - terminate core
        case ER_BAD_FIELD_ERROR:
        case ER_NO_SUCH_TABLE:
            TC_LOG_ERROR("sql.sql", "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
            std::this_thread::sleep_for(std::chrono::seconds(10));
            std::abort();
            return false;
        case ER_PARSE_ERROR:
            TC_LOG_ERROR("sql.sql", "Error while parsing SQL. Core fix required.");
            std::this_thread::sleep_for(std::chrono::seconds(10));
            std::abort();
            return false;
        default:
            TC_LOG_ERROR("sql.sql", "Unhandled MySQL errno %u. Unexpected behaviour possible.", errNo);
            return false;
    }
}
예제 #22
0
bool MySqlConnection::_HandleMySQLErrno(uint32 errNo)
{
	switch (errNo)
	{
		case CR_SERVER_GONE_ERROR:
		case CR_SERVER_LOST:
		case CR_INVALID_CONN_HANDLE:
		case CR_SERVER_LOST_EXTENDED:
		{
			m_reconnecting = true;
			mysql_close(GetHandle());
			if (this->Open())
			{
				m_reconnecting = false;
				DEBUG_LOG("mysql connect reconnect success\n");
				return true;
			}
			uint32 lErrno = mysql_errno(GetHandle());   // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
			::sleep(3);                           // Sleep 3 seconds
			return _HandleMySQLErrno(lErrno);           // Call self (recursive)
		}
		break;
		case ER_LOCK_DEADLOCK:
		{
			return false;    // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction
		}
		break;
		// Query related errors - skip query
		case ER_WRONG_VALUE_COUNT:
		case ER_DUP_ENTRY:
		{
			return false;
		}
		break;
		// Outdated table or database structure - terminate core
		case ER_BAD_FIELD_ERROR:
		case ER_NO_SUCH_TABLE:
		{
			ERROR_LOG("Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.\n");
			::sleep(10);
			std::abort();
			return false;
		}
		break;
		case ER_PARSE_ERROR:
		{
			ERROR_LOG("Error while parsing SQL. Core fix required.\n");
			::sleep(10);
			std::abort();
			return false;
		}
		break;
		default:
		{
			ERROR_LOG("Unhandled MySQL errno %u. Unexpected behaviour possible.\n", errNo);
			return false;	
		}
		break;
	}
	
	return false;
}