28#include <boost/filesystem/operations.hpp>
43 if (!is_regular_file(exe))
46 if (!exe.empty() && is_regular_file(exe))
53 TC_LOG_FATAL(
"sql.updates",
"Didn't find any executable MySQL binary at \'{}\' or in path, correct the path in the *.conf (\"MySQLExecutable\").",
54 absolute(exe).generic_string());
63 static std::string path;
71 return "Updates.Auth";
84 "/sql/base/auth_database.sql";
98 return "Updates.World";
130 return "Updates.Character";
143 "/sql/base/characters_database.sql";
163 TC_LOG_INFO(
"sql.updates",
"Database \"{}\" does not exist, do you want to create it? [yes (default) / no]: ",
167 std::getline(std::cin, answer);
168 if (!answer.empty() && !(answer.substr(0, 1) ==
"y"))
174 static Path const temp(
"create_table.sql");
177 std::ofstream file(temp.generic_string());
180 TC_LOG_FATAL(
"sql.updates",
"Failed to create temporary query file \"{}\"!", temp.generic_string());
184 file <<
"CREATE DATABASE `" << pool.
GetConnectionInfo()->
database <<
"` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci\n\n";
195 TC_LOG_FATAL(
"sql.updates",
"Failed to create database {}! Does the user (named in *.conf) have `CREATE`, `ALTER`, `DROP`, `INSERT` and `DELETE` privileges on the MySQL server?", pool.
GetConnectionInfo()->
database);
196 boost::filesystem::remove(temp);
201 boost::filesystem::remove(temp);
215 if (!is_directory(sourceDirectory))
217 TC_LOG_ERROR(
"sql.updates",
"DBUpdater: The given source directory {} does not exist, change the path to the directory where your sql directory exists (for example c:\\source\\trinitycore). Shutting down.", sourceDirectory.generic_string());
228 result = updateFetcher.Update(
229 sConfigMgr->GetBoolDefault(
"Updates.Redundancy",
true),
230 sConfigMgr->GetBoolDefault(
"Updates.AllowRehash",
true),
231 sConfigMgr->GetBoolDefault(
"Updates.ArchivedRedundancy",
false),
232 sConfigMgr->GetIntDefault(
"Updates.CleanDeadRefMaxCount", 3));
240 result.recent, result.archived);
245 TC_LOG_INFO(
"sql.updates",
">> Applied {} {}. {}", result.updated, result.updated == 1 ?
"query" :
"queries", info);
254 QueryResult const result = Retrieve(pool,
"SHOW TABLES");
255 if (result && (result->GetRowCount() > 0))
267 TC_LOG_INFO(
"sql.updates",
">> No base file provided, skipped!");
278 TC_LOG_ERROR(
"sql.updates",
">> Base file \"{}\" is missing. Try fixing it by cloning the source again.",
279 base.generic_string());
285 std::string
const filename = base.filename().generic_string();
286 std::string
const workdir = boost::filesystem::current_path().generic_string();
287 TC_LOG_ERROR(
"sql.updates",
">> File \"{}\" is missing, download it from \"https://github.com/TrinityCore/TrinityCore/releases\"" \
288 " uncompress it and place the file \"{}\" in the directory \"{}\".", filename, filename, workdir);
296 TC_LOG_INFO(
"sql.updates",
">> Applying \'{}\'...", base.generic_string());
299 ApplyFile(pool, base);
313 return pool.
Query(query.c_str());
331 std::string
const& password, std::string
const& port_or_socket, std::string
const& database, std::string
const& ssl,
334 std::vector<std::string> args;
338 args.emplace_back(
"-h" + host);
339 args.emplace_back(
"-u" + user);
341 if (!password.empty())
342 args.emplace_back(
"-p" + password);
348 args.emplace_back(
"--protocol=PIPE");
350 args.emplace_back(
"-P" + port_or_socket);
354 if (!std::isdigit(port_or_socket[0]))
357 args.emplace_back(
"-P0");
358 args.emplace_back(
"--protocol=SOCKET");
359 args.emplace_back(
"-S" + port_or_socket);
363 args.emplace_back(
"-P" + port_or_socket);
368 args.emplace_back(
"--default-character-set=utf8mb4");
371 args.emplace_back(
"--max-allowed-packet=1GB");
373#if !defined(MARIADB_VERSION_ID) && MYSQL_VERSION_ID >= 80000
376 args.emplace_back(
"--ssl-mode=REQUIRED");
378#if MYSQL_VERSION_ID >= 90400
382 args.emplace_back(
"--commands=ON");
389 args.emplace_back(
"--ssl");
394 args.emplace_back(
"-e");
398 if (!database.empty())
399 args.emplace_back(database);
403 "sql.updates",
"",
true);
405 if (ret != EXIT_SUCCESS)
407 TC_LOG_FATAL(
"sql.updates",
"Applying of file \'{}\' to database \'{}\' failed!" \
408 " If you are a user, please pull the latest revision from the repository. "
409 "Also make sure you have not applied any of the databases with your sql client. "
410 "You cannot use auto-update system and import sql files from TrinityCore repository with your sql client. "
411 "If you are a developer, please fix your sql query.",
std::shared_ptr< ResultSet > QueryResult
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
#define TC_LOG_FATAL(filterType__,...)
static std::string & corrected_path()
static bool CheckExecutable()
static std::string GetCorrectedMySQLExecutable()
static BaseLocation GetBaseLocationType()
static bool Update(DatabaseWorkerPool< T > &pool)
boost::filesystem::path Path
static QueryResult Retrieve(DatabaseWorkerPool< T > &pool, std::string const &query)
static std::string GetBaseFile()
static void Apply(DatabaseWorkerPool< T > &pool, std::string const &query)
static bool Create(DatabaseWorkerPool< T > &pool)
static std::string GetTableName()
static void ApplyFile(DatabaseWorkerPool< T > &pool, Path const &path)
static bool IsEnabled(uint32 const updateMask)
static bool Populate(DatabaseWorkerPool< T > &pool)
static std::string GetConfigEntry()
QueryResult Query(char const *sql, T *connection=nullptr)
MySQLConnectionInfo const * GetConnectionInfo() const
void DirectExecute(char const *sql)
TC_COMMON_API std::string GetSourceDirectory()
TC_COMMON_API std::string GetMySQLExecutable()
TC_COMMON_API char const * GetFullDatabase()
std::string SearchExecutableInPath(std::string const &filename)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.
int32 StartProcess(std::string executable, std::vector< std::string > args, std::string logger, std::string input_file, bool secure)
std::string port_or_socket