Skip to content

Commit

Permalink
fix(Core/DatabseWorkerPool): implement DatabaseIncompatibleVersion to…
Browse files Browse the repository at this point in the history
… better support MariaDB (azerothcore#18201)

* fix(Core): Rework Database Version Check for MariaDB support

* incorporate "smarter" version comparison

* rename function to be more accurate

* Factor magic numbers into defines. Revise comments

* clean up triple newline

* Doxygenify the docs

* remove blankspace

---------

Co-authored-by: Kitzunu <[email protected]>
  • Loading branch information
michaeldelago and Kitzunu authored Jan 21, 2024
1 parent e447351 commit d0eae39
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 11 deletions.
71 changes: 61 additions & 10 deletions src/server/database/Database/DatabaseWorkerPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,14 @@
#include "WorldDatabase.h"
#include <limits>
#include <mysqld_error.h>
#include <sstream>
#include <vector>

#ifdef ACORE_DEBUG
#include <boost/stacktrace.hpp>
#include <sstream>
#endif

#if MARIADB_VERSION_ID >= 100600
#define MIN_MYSQL_SERVER_VERSION 100500u
#define MIN_MYSQL_CLIENT_VERSION 30203u
#else
#define MIN_MYSQL_SERVER_VERSION 50700u
#define MIN_MYSQL_CLIENT_VERSION 50700u
#endif

class PingOperation : public SQLOperation
{
//! Operation for idle delaythreads
Expand Down Expand Up @@ -377,6 +371,63 @@ void DatabaseWorkerPool<T>::KeepAlive()
Enqueue(new PingOperation);
}

/**
* @brief Returns true if the version string given is incompatible
*
* Intended to be used with mysql_get_server_info()'s output as the source
*
* DatabaseIncompatibleVersion("8.0.35") => false
* DatabaseIncompatibleVersion("5.6.6") => true
* DatabaseIncompatibleVersion("5.5.5-10.5.5-MariaDB") => false
* DatabaseIncompatibleVersion("5.5.5-10.4.0-MariaDB") => true
*
* Adapted from stackoverflow response
* https://stackoverflow.com/a/2941508
*
* @param mysqlVersion The output from GetServerInfo()/mysql_get_server_info()
* @return Returns true if the Server version is incompatible
*/
bool DatabaseIncompatibleVersion(std::string const mysqlVersion)
{
// anon func to turn a version string into an array of uint8
// "1.2.3" => [1, 2, 3]
auto parse = [](std::string const& input)
{
std::vector<uint8> result;
std::istringstream parser(input);
result.push_back(parser.get());
for (int i = 1; i < 3; i++)
{
// Skip period
parser.get();
// Append int from parser to output
result.push_back(parser.get());
}
return result;
};

// default to values for MySQL
uint8 offset = 0;
std::string minVersion = MIN_MYSQL_SERVER_VERSION;

// If the version string contains "MariaDB", use that
if (mysqlVersion.find("MariaDB") != std::string::npos)
{
// All MariaDB 10.X versions have a prefix of 5.5.5 from the
// mysql_get_server_info() function. To make matters more
// annoying, this is removed in MariaDB 11.X
if (mysqlVersion.rfind("5.5.5-", 0) == 0)
offset = 6;
minVersion = MIN_MARIADB_SERVER_VERSION;
}

auto parsedMySQLVersion = parse(mysqlVersion.substr(offset));
auto parsedMinVersion = parse(minVersion);

return std::lexicographical_compare(parsedMySQLVersion.begin(), parsedMySQLVersion.end(),
parsedMinVersion.begin(), parsedMinVersion.end());
}

template <class T>
uint32 DatabaseWorkerPool<T>::OpenConnections(InternalIndex type, uint8 numConnections)
{
Expand All @@ -402,10 +453,10 @@ uint32 DatabaseWorkerPool<T>::OpenConnections(InternalIndex type, uint8 numConne
_connections[type].clear();
return error;
}
else if (connection->GetServerVersion() < MIN_MYSQL_SERVER_VERSION)
else if (DatabaseIncompatibleVersion(connection->GetServerInfo()))
{
LOG_ERROR("sql.driver", "AzerothCore does not support MySQL versions below 5.7 or MariaDB versions below 10.5.\n\nFound server version: {}. Server compiled with: {}.",
connection->GetServerVersion(), MYSQL_VERSION_ID);
connection->GetServerInfo(), MYSQL_VERSION_ID);
return 1;
}
else
Expand Down
28 changes: 28 additions & 0 deletions src/server/database/Database/DatabaseWorkerPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,34 @@
#include <array>
#include <vector>

/** @file DatabaseWorkerPool.h */

/**
* @def MIN_MYSQL_CLIENT_VERSION
* The minimum MariaDB Client Version
* MARIADB_VERSION_ID is defined if using libmariadbclient instead of libmysqlclient
*/
#if MARIADB_VERSION_ID >= 100600
#define MIN_MYSQL_CLIENT_VERSION 30203u
#else
/**
* @def MIN_MYSQL_CLIENT_VERSION
* The minimum MySQL Client Version
*/
#define MIN_MYSQL_CLIENT_VERSION 50700u
#endif

/**
* @def MIN_MYSQL_SERVER_VERSION
* The minimum MySQL Server Version
*/
#define MIN_MYSQL_SERVER_VERSION "5.7.0"
/**
* @def MIN_MARIADB_SERVER_VERSION
* The minimum MariaDB Server Version
*/
#define MIN_MARIADB_SERVER_VERSION "10.5.0"

template <typename T>
class ProducerConsumerQueue;

Expand Down
7 changes: 6 additions & 1 deletion src/server/database/Database/MySQLConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
#include "Timer.h"
#include "Tokenize.h"
#include "Transaction.h"
#include "Util.h"
#include <errmsg.h>
#include <mysql.h>
#include <mysqld_error.h>

MySQLConnectionInfo::MySQLConnectionInfo(std::string_view infoString)
Expand Down Expand Up @@ -486,6 +486,11 @@ uint32 MySQLConnection::GetServerVersion() const
return mysql_get_server_version(m_Mysql);
}

std::string MySQLConnection::GetServerInfo() const
{
return mysql_get_server_info(m_Mysql);
}

MySQLPreparedStatement* MySQLConnection::GetPreparedStatement(uint32 index)
{
ASSERT(index < m_stmts.size(), "Tried to access invalid prepared statement index {} (max index {}) on database `{}`, connection type: {}",
Expand Down
1 change: 1 addition & 0 deletions src/server/database/Database/MySQLConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ friend class PingOperation;
void Unlock();

[[nodiscard]] uint32 GetServerVersion() const;
[[nodiscard]] std::string GetServerInfo() const;
MySQLPreparedStatement* GetPreparedStatement(uint32 index);
void PrepareStatement(uint32 index, std::string_view sql, ConnectionFlags flags);

Expand Down

0 comments on commit d0eae39

Please sign in to comment.