Skip to content

Commit 521ec0b

Browse files
committed
Dep/MySQL: Move required version checks to CMake, raise required version to 8.0.34 and remove strict compiled<->runtime version match requirement from non-Windows platforms
(cherry picked from commit b386971229f5ad389be9e22cbb96c39d79ac7beb)
1 parent 101b0e0 commit 521ec0b

File tree

4 files changed

+113
-70
lines changed

4 files changed

+113
-70
lines changed

cmake/macros/FindMySQL.cmake

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,19 @@ This module will set the following variables in your project:
4040
MySQL library.
4141
``MYSQL_EXECUTABLE``
4242
Path to mysql client binary.
43+
``MYSQL_FLAVOR``
44+
Flavor of mysql installation (MySQL or MariaDB).
45+
``MYSQL_VERSION``
46+
MySQL version string.
4347
4448
Hints
4549
^^^^^
4650
4751
Set ``MYSQL_ROOT_DIR`` to the root directory of MySQL installation.
4852
#]=======================================================================]
4953

54+
include(FindPackageHandleStandardArgs)
55+
5056
set(MYSQL_FOUND 0)
5157

5258
set(_MYSQL_ROOT_HINTS
@@ -219,30 +225,16 @@ endif(WIN32)
219225
# On Windows you typically don't need to include any extra libraries
220226
# to build MYSQL stuff.
221227

222-
if(NOT WIN32)
223-
find_library(MYSQL_EXTRA_LIBRARIES
224-
NAMES
225-
z zlib
226-
PATHS
227-
/usr/lib
228-
/usr/local/lib
229-
DOC
230-
"if more libraries are necessary to link in a MySQL client (typically zlib), specify them here."
231-
)
232-
else(NOT WIN32)
233-
set(MYSQL_EXTRA_LIBRARIES "")
234-
endif(NOT WIN32)
235-
236228
if(UNIX)
237-
find_program(MYSQL_EXECUTABLE mysql
238-
PATHS
239-
${MYSQL_CONFIG_PREFER_PATH}
240-
/usr/local/mysql/bin/
241-
/usr/local/bin/
242-
/usr/bin/
243-
DOC
244-
"path to your mysql binary."
245-
)
229+
find_program(MYSQL_EXECUTABLE mysql
230+
PATHS
231+
${MYSQL_CONFIG_PREFER_PATH}
232+
/usr/local/mysql/bin/
233+
/usr/local/bin/
234+
/usr/bin/
235+
DOC
236+
"path to your mysql binary."
237+
)
246238
endif(UNIX)
247239

248240
if(WIN32)
@@ -291,7 +283,6 @@ foreach(_comp IN LISTS MySQL_FIND_COMPONENTS)
291283
endforeach()
292284
unset(_comp)
293285

294-
include(FindPackageHandleStandardArgs)
295286
find_package_handle_standard_args(MySQL
296287
REQUIRED_VARS
297288
${MYSQL_REQUIRED_VARS}
@@ -301,25 +292,37 @@ find_package_handle_standard_args(MySQL
301292
)
302293
unset(MYSQL_REQUIRED_VARS)
303294

304-
if(MYSQL_FOUND)
305-
if(MySQL_lib_WANTED AND MySQL_lib_FOUND)
306-
message(STATUS "Found MySQL library: ${MYSQL_LIBRARY}")
307-
message(STATUS "Found MySQL headers: ${MYSQL_INCLUDE_DIR}")
308-
endif()
309-
if(MySQL_binary_WANTED AND MySQL_binary_FOUND)
310-
message(STATUS "Found MySQL executable: ${MYSQL_EXECUTABLE}")
311-
endif()
312-
mark_as_advanced(MYSQL_FOUND MYSQL_LIBRARY MYSQL_EXTRA_LIBRARIES MYSQL_INCLUDE_DIR MYSQL_EXECUTABLE)
313-
314-
if(NOT TARGET MySQL::MySQL AND MySQL_lib_WANTED AND MySQL_lib_FOUND)
315-
add_library(MySQL::MySQL UNKNOWN IMPORTED)
316-
set_target_properties(MySQL::MySQL
317-
PROPERTIES
318-
IMPORTED_LOCATION
319-
"${MYSQL_LIBRARY}"
320-
INTERFACE_INCLUDE_DIRECTORIES
321-
"${MYSQL_INCLUDE_DIR}")
295+
if(MySQL_lib_WANTED AND MySQL_lib_FOUND)
296+
try_run(MYSQL_VERSION_DETECTED MYSQL_VERSION_COMPILED ${CMAKE_BINARY_DIR}
297+
SOURCES "${CMAKE_CURRENT_LIST_DIR}/FindMySQLVersion.c"
298+
CMAKE_FLAGS -DINCLUDE_DIRECTORIES=${MYSQL_INCLUDE_DIR}
299+
LINK_LIBRARIES ${MYSQL_LIBRARY}
300+
RUN_OUTPUT_VARIABLE MYSQL_VERSION_DETECTION_RUN_OUTPUT
301+
)
302+
303+
string(JSON MYSQL_VERSION GET "${MYSQL_VERSION_DETECTION_RUN_OUTPUT}" "version")
304+
string(JSON MYSQL_FLAVOR GET "${MYSQL_VERSION_DETECTION_RUN_OUTPUT}" "flavor")
305+
306+
if(MYSQL_MIN_VERSION_${MYSQL_FLAVOR} VERSION_GREATER MYSQL_VERSION)
307+
message(FATAL_ERROR "Found ${MYSQL_FLAVOR} version: \"${MYSQL_VERSION}\", but required is at least \"${MYSQL_MIN_VERSION_${MYSQL_FLAVOR}}\"")
308+
else()
309+
message(STATUS "Found ${MYSQL_FLAVOR} version: \"${MYSQL_VERSION}\", minimum required is \"${MYSQL_MIN_VERSION_${MYSQL_FLAVOR}}\"")
322310
endif()
323-
else()
324-
message(FATAL_ERROR "Could not find the MySQL libraries! Please install the development libraries and headers")
311+
312+
message(STATUS "Found ${MYSQL_FLAVOR} library: ${MYSQL_LIBRARY}")
313+
message(STATUS "Found ${MYSQL_FLAVOR} headers: ${MYSQL_INCLUDE_DIR}")
314+
endif()
315+
if(MySQL_binary_WANTED AND MySQL_binary_FOUND)
316+
message(STATUS "Found MySQL executable: ${MYSQL_EXECUTABLE}")
317+
endif()
318+
mark_as_advanced(MYSQL_FOUND MYSQL_LIBRARY MYSQL_INCLUDE_DIR MYSQL_EXECUTABLE)
319+
320+
if(NOT TARGET MySQL::MySQL AND MySQL_lib_WANTED AND MySQL_lib_FOUND)
321+
add_library(MySQL::MySQL UNKNOWN IMPORTED)
322+
set_target_properties(MySQL::MySQL
323+
PROPERTIES
324+
IMPORTED_LOCATION
325+
"${MYSQL_LIBRARY}"
326+
INTERFACE_INCLUDE_DIRECTORIES
327+
"${MYSQL_INCLUDE_DIR}")
325328
endif()

cmake/macros/FindMySQLVersion.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <mysql.h>
2+
#include <stdio.h>
3+
4+
int main()
5+
{
6+
printf("{ "
7+
"\"version\": \"%d.%d.%d\", "
8+
"\"flavor\": \"%s\""
9+
" }",
10+
MYSQL_VERSION_ID / 10000, (MYSQL_VERSION_ID / 100) % 100, MYSQL_VERSION_ID % 100,
11+
#ifdef MARIADB_VERSION_ID
12+
"MariaDB"
13+
#else
14+
"MySQL"
15+
#endif
16+
);
17+
return 0;
18+
}

dep/mysql/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,17 @@
88
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
99
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1010

11-
find_package(MySQL REQUIRED COMPONENTS lib)
11+
set(MYSQL_MIN_VERSION_MySQL 8.0.34)
12+
set(MYSQL_MIN_VERSION_MariaDB 10.4)
13+
find_package(MySQL COMPONENTS lib)
1214

1315
add_library(mysql INTERFACE)
1416

17+
target_compile_definitions(mysql
18+
INTERFACE
19+
TRINITY_MYSQL_FLAVOR="${MYSQL_FLAVOR}"
20+
TRINITY_REQUIRED_MYSQL_VERSION="${MYSQL_MIN_VERSION_${MYSQL_FLAVOR}}")
21+
1522
target_link_libraries(mysql
1623
INTERFACE
1724
MySQL::MySQL)

src/server/database/Database/DatabaseWorkerPool.cpp

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,36 @@
3838
#include <boost/stacktrace.hpp>
3939
#endif
4040

41-
#define MIN_MYSQL_SERVER_VERSION 50700u
42-
#define MIN_MYSQL_SERVER_VERSION_STRING "5.7"
43-
#define MIN_MYSQL_CLIENT_VERSION 50700u
44-
#define MIN_MYSQL_CLIENT_VERSION_STRING "5.7"
41+
static consteval uint32 ParseVersionString(std::string_view chars)
42+
{
43+
uint32 result = 0;
44+
uint32 partialResult = 0;
45+
uint32 multiplier = 10000;
46+
for (std::size_t i = 0; i < chars.length(); ++i)
47+
{
48+
char c = chars[i];
49+
if (c == '.')
50+
{
51+
if (multiplier < 100)
52+
throw "Too many . characters in version string";
53+
54+
result += partialResult * multiplier;
55+
multiplier /= 100;
56+
partialResult = 0;
57+
}
58+
else if (c >= '0' && c <= '9')
59+
{
60+
partialResult *= 10;
61+
partialResult += c - '0';
62+
}
63+
else
64+
throw "Invalid input character";
65+
}
4566

46-
#define MIN_MARIADB_SERVER_VERSION 100209u
47-
#define MIN_MARIADB_SERVER_VERSION_STRING "10.2.9"
48-
#define MIN_MARIADB_CLIENT_VERSION 30003u
49-
#define MIN_MARIADB_CLIENT_VERSION_STRING "3.0.3"
67+
result += partialResult * multiplier;
68+
69+
return result;
70+
}
5071

5172
class PingOperation : public SQLOperation
5273
{
@@ -63,14 +84,17 @@ DatabaseWorkerPool<T>::DatabaseWorkerPool()
6384
: _queue(new ProducerConsumerQueue<SQLOperation*>()),
6485
_async_threads(0), _synch_threads(0)
6586
{
66-
WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe.");
67-
87+
// We only need check compiled version match on Windows
88+
// because on other platforms ABI compatibility is ensured by SOVERSION
89+
// and Windows MySQL releases don't even have abi-version-like component in their dll file name
90+
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
6891
#if defined(LIBMARIADB) && MARIADB_PACKAGE_VERSION_ID >= 30200
69-
WPFatal(mysql_get_client_version() >= MIN_MARIADB_CLIENT_VERSION, "TrinityCore does not support MariaDB versions below " MIN_MARIADB_CLIENT_VERSION_STRING " (found %s id %lu, need id >= %u), please update your MariaDB client library", mysql_get_client_info(), mysql_get_client_version(), MIN_MARIADB_CLIENT_VERSION);
70-
WPFatal(mysql_get_client_version() == MARIADB_PACKAGE_VERSION_ID, "Used MariaDB library version (%s id %lu) does not match the version id used to compile TrinityCore (id %u). Search on forum for TCE00011.", mysql_get_client_info(), mysql_get_client_version(), MARIADB_PACKAGE_VERSION_ID);
92+
#define TRINITY_COMPILED_CLIENT_VERSION MARIADB_PACKAGE_VERSION_ID
7193
#else
72-
WPFatal(mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below " MIN_MYSQL_CLIENT_VERSION_STRING " (found %s id %lu, need id >= %u), please update your MySQL client library", mysql_get_client_info(), mysql_get_client_version(), MIN_MYSQL_CLIENT_VERSION);
73-
WPFatal(mysql_get_client_version() == MYSQL_VERSION_ID, "Used MySQL library version (%s id %lu) does not match the version id used to compile TrinityCore (id %u). Search on forum for TCE00011.", mysql_get_client_info(), mysql_get_client_version(), MYSQL_VERSION_ID);
94+
#define TRINITY_COMPILED_CLIENT_VERSION MYSQL_VERSION_ID
95+
#endif
96+
WPFatal(mysql_get_client_version() == TRINITY_COMPILED_CLIENT_VERSION, "Used " TRINITY_MYSQL_FLAVOR " library version (%s id %lu) does not match the version id used to compile TrinityCore (id %u). Search on forum for TCE00011.", mysql_get_client_info(), mysql_get_client_version(), TRINITY_COMPILED_CLIENT_VERSION);
97+
#undef TRINITY_COMPILED_CLIENT_VERSION
7498
#endif
7599
}
76100

@@ -395,18 +419,9 @@ uint32 DatabaseWorkerPool<T>::OpenConnections(InternalIndex type, uint8 numConne
395419
_connections[type].clear();
396420
return error;
397421
}
398-
#ifndef LIBMARIADB
399-
else if (connection->GetServerVersion() < MIN_MYSQL_SERVER_VERSION)
400-
#else
401-
else if (connection->GetServerVersion() < MIN_MARIADB_SERVER_VERSION)
402-
#endif
422+
else if (uint32 serverVersion = connection->GetServerVersion(); serverVersion < ParseVersionString(TRINITY_REQUIRED_MYSQL_VERSION))
403423
{
404-
#ifndef LIBMARIADB
405-
TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below " MIN_MYSQL_SERVER_VERSION_STRING " (found id {}, need id >= {}), please update your MySQL server", connection->GetServerVersion(), MIN_MYSQL_SERVER_VERSION);
406-
#else
407-
TC_LOG_ERROR("sql.driver", "TrinityCore does not support MariaDB versions below " MIN_MARIADB_SERVER_VERSION_STRING " (found id {}, need id >= {}), please update your MySQL server", connection->GetServerVersion(), MIN_MARIADB_SERVER_VERSION);
408-
#endif
409-
424+
TC_LOG_ERROR("sql.driver", "TrinityCore does not support " TRINITY_MYSQL_FLAVOR " versions below " TRINITY_REQUIRED_MYSQL_VERSION " (found id {}, need id >= {}), please update your " TRINITY_MYSQL_FLAVOR " server", serverVersion, ParseVersionString(TRINITY_REQUIRED_MYSQL_VERSION));
410425
return 1;
411426
}
412427
else

0 commit comments

Comments
 (0)