TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
DBUpdater< T > Class Template Reference

#include <DBUpdater.h>

Public Types

using Path = boost::filesystem::path
 

Public Member Functions

template<>
std::string GetConfigEntry ()
 
template<>
std::string GetTableName ()
 
template<>
std::string GetBaseFile ()
 
template<>
bool IsEnabled (uint32 const updateMask)
 
template<>
std::string GetConfigEntry ()
 
template<>
std::string GetTableName ()
 
template<>
std::string GetBaseFile ()
 
template<>
bool IsEnabled (uint32 const updateMask)
 
template<>
BaseLocation GetBaseLocationType ()
 
template<>
std::string GetConfigEntry ()
 
template<>
std::string GetTableName ()
 
template<>
std::string GetBaseFile ()
 
template<>
bool IsEnabled (uint32 const updateMask)
 
template<>
std::string GetConfigEntry ()
 
template<>
std::string GetTableName ()
 
template<>
std::string GetBaseFile ()
 
template<>
bool IsEnabled (uint32 const updateMask)
 
template<>
BaseLocation GetBaseLocationType ()
 

Static Public Member Functions

static std::string GetConfigEntry ()
 
static std::string GetTableName ()
 
static std::string GetBaseFile ()
 
static bool IsEnabled (uint32 const updateMask)
 
static BaseLocation GetBaseLocationType ()
 
static bool Create (DatabaseWorkerPool< T > &pool)
 
static bool Update (DatabaseWorkerPool< T > &pool)
 
static bool Populate (DatabaseWorkerPool< T > &pool)
 

Static Private Member Functions

static QueryResult Retrieve (DatabaseWorkerPool< T > &pool, std::string const &query)
 
static void Apply (DatabaseWorkerPool< T > &pool, std::string const &query)
 
static void ApplyFile (DatabaseWorkerPool< T > &pool, Path const &path)
 
static void ApplyFile (DatabaseWorkerPool< T > &pool, std::string const &host, std::string const &user, std::string const &password, std::string const &port_or_socket, std::string const &database, Path const &path)
 

Member Typedef Documentation

template<class T >
using DBUpdater< T >::Path = boost::filesystem::path

Member Function Documentation

template<class T >
void DBUpdater< T >::Apply ( DatabaseWorkerPool< T > &  pool,
std::string const query 
)
staticprivate
364 {
365  pool.DirectExecute(query.c_str());
366 }
char * query(struct soap *soap)
Definition: httpget.cpp:244
void DirectExecute(const char *sql)
Definition: DatabaseWorkerPool.h:121

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T >
void DBUpdater< T >::ApplyFile ( DatabaseWorkerPool< T > &  pool,
Path const path 
)
staticprivate
370 {
371  DBUpdater<T>::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password,
372  pool.GetConnectionInfo()->port_or_socket, pool.GetConnectionInfo()->database, path);
373 }
MySQLConnectionInfo const * GetConnectionInfo() const
Definition: DatabaseWorkerPool.h:76
static void ApplyFile(DatabaseWorkerPool< T > &pool, Path const &path)
Definition: DBUpdater.cpp:369

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T >
void DBUpdater< T >::ApplyFile ( DatabaseWorkerPool< T > &  pool,
std::string const host,
std::string const user,
std::string const password,
std::string const port_or_socket,
std::string const database,
Path const path 
)
staticprivate
378 {
379  std::vector<std::string> args;
380  args.reserve(8);
381 
382  // args[0] represents the program name
383  args.push_back("mysql");
384 
385  // CLI Client connection info
386  args.push_back("-h" + host);
387  args.push_back("-u" + user);
388 
389  if (!password.empty())
390  args.push_back("-p" + password);
391 
392  // Check if we want to connect through ip or socket (Unix only)
393 #ifdef _WIN32
394 
395  args.push_back("-P" + port_or_socket);
396 
397 #else
398 
399  if (!std::isdigit(port_or_socket[0]))
400  {
401  // We can't check here if host == "." because is named localhost if socket option is enabled
402  args.push_back("-P0");
403  args.push_back("--protocol=SOCKET");
404  args.push_back("-S" + port_or_socket);
405  }
406  else
407  // generic case
408  args.push_back("-P" + port_or_socket);
409 
410 #endif
411 
412  // Set the default charset to utf8
413  args.push_back("--default-character-set=utf8");
414 
415  // Set max allowed packet to 1 GB
416  args.push_back("--max-allowed-packet=1GB");
417 
418  // Database
419  if (!database.empty())
420  args.push_back(database);
421 
422  // ToDo: use the existing query in memory as virtual file if possible
423  file_descriptor_source source(path);
424 
425  uint32 ret;
426  try
427  {
428  boost::process::pipe outPipe = create_pipe();
429  boost::process::pipe errPipe = create_pipe();
430 
431  child c = execute(run_exe(
432  boost::filesystem::absolute(DBUpdaterUtil::GetCorrectedMySQLExecutable()).generic_string()),
433  set_args(args), bind_stdin(source), throw_on_error(),
434  bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
435  bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
436 
437  file_descriptor_source mysqlOutfd(outPipe.source, close_handle);
438  file_descriptor_source mysqlErrfd(errPipe.source, close_handle);
439 
440  stream<file_descriptor_source> mysqlOutStream(mysqlOutfd);
441  stream<file_descriptor_source> mysqlErrStream(mysqlErrfd);
442 
443  std::stringstream out;
444  std::stringstream err;
445 
446  copy(mysqlOutStream, out);
447  copy(mysqlErrStream, err);
448 
449  TC_LOG_INFO("sql.updates", "%s", out.str().c_str());
450  TC_LOG_ERROR("sql.updates", "%s", err.str().c_str());
451 
452  ret = wait_for_exit(c);
453  }
454  catch (boost::system::system_error&)
455  {
456  ret = EXIT_FAILURE;
457  }
458 
459  source.close();
460 
461  if (ret != EXIT_SUCCESS)
462  {
463  TC_LOG_FATAL("sql.updates", "Applying of file \'%s\' to database \'%s\' failed!" \
464  " If you are an user pull the latest revision from the repository. If you are a developer fix your sql query.",
465  path.generic_string().c_str(), pool.GetConnectionInfo()->database.c_str());
466 
467  throw UpdateException("update failed");
468  }
469 }
Definition: DBUpdater.h:26
MySQLConnectionInfo const * GetConnectionInfo() const
Definition: DatabaseWorkerPool.h:76
uint32_t uint32
Definition: Define.h:150
static std::string GetCorrectedMySQLExecutable()
Definition: DBUpdater.cpp:39
#define TC_LOG_FATAL(filterType__,...)
Definition: Log.h:210
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207

+ Here is the call graph for this function:

template<class T >
bool DBUpdater< T >::Create ( DatabaseWorkerPool< T > &  pool)
static
210 {
211  TC_LOG_INFO("sql.updates", "Database \"%s\" does not exist, do you want to create it? [yes (default) / no]: ",
212  pool.GetConnectionInfo()->database.c_str());
213 
214  std::string answer;
215  std::getline(std::cin, answer);
216  if (!answer.empty() && !(answer.substr(0, 1) == "y"))
217  return false;
218 
219  TC_LOG_INFO("sql.updates", "Creating database \"%s\"...", pool.GetConnectionInfo()->database.c_str());
220 
221  // Path of temp file
222  static Path const temp("create_table.sql");
223 
224  // Create temporary query to use external mysql cli
225  std::ofstream file(temp.generic_string());
226  if (!file.is_open())
227  {
228  TC_LOG_FATAL("sql.updates", "Failed to create temporary query file \"%s\"!", temp.generic_string().c_str());
229  return false;
230  }
231 
232  file << "CREATE DATABASE `" << pool.GetConnectionInfo()->database << "` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci\n\n";
233 
234  file.close();
235 
236  try
237  {
238  DBUpdater<T>::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password,
239  pool.GetConnectionInfo()->port_or_socket, "", temp);
240  }
241  catch (UpdateException&)
242  {
243  TC_LOG_FATAL("sql.updates", "Failed to create database %s! Has the user `CREATE` priviliges?", pool.GetConnectionInfo()->database.c_str());
244  boost::filesystem::remove(temp);
245  return false;
246  }
247 
248  TC_LOG_INFO("sql.updates", "Done.");
249  boost::filesystem::remove(temp);
250  return true;
251 }
Definition: DBUpdater.h:26
boost::filesystem::path Path
Definition: DBUpdater.h:72
MySQLConnectionInfo const * GetConnectionInfo() const
Definition: DatabaseWorkerPool.h:76
#define TC_LOG_FATAL(filterType__,...)
Definition: Log.h:210
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
static void ApplyFile(DatabaseWorkerPool< T > &pool, Path const &path)
Definition: DBUpdater.cpp:369

+ Here is the call graph for this function:

template<class T >
static std::string DBUpdater< T >::GetBaseFile ( )
static

+ Here is the caller graph for this function:

template<>
std::string DBUpdater< LoginDatabaseConnection >::GetBaseFile ( )
98 {
100  "/sql/base/auth_database.sql";
101 }
TC_COMMON_API std::string GetSourceDirectory()
Definition: BuiltInConfig.cpp:42

+ Here is the call graph for this function:

template<>
std::string DBUpdater< WorldDatabaseConnection >::GetBaseFile ( )
125 {
127 }
TC_COMMON_API char const * GetFullDatabase()
Definition: GitRevision.cpp:39

+ Here is the call graph for this function:

template<>
std::string DBUpdater< CharacterDatabaseConnection >::GetBaseFile ( )
157 {
159  "/sql/base/characters_database.sql";
160 }
TC_COMMON_API std::string GetSourceDirectory()
Definition: BuiltInConfig.cpp:42

+ Here is the call graph for this function:

template<>
std::string DBUpdater< HotfixDatabaseConnection >::GetBaseFile ( )
184 {
186 }
TC_COMMON_API char const * GetHotfixesDatabase()
Definition: GitRevision.cpp:44

+ Here is the call graph for this function:

template<class T >
BaseLocation DBUpdater< T >::GetBaseLocationType ( )
static
204 {
205  return LOCATION_REPOSITORY;
206 }
Definition: DBUpdater.h:40
template<>
BaseLocation DBUpdater< WorldDatabaseConnection >::GetBaseLocationType ( )
138 {
139  return LOCATION_DOWNLOAD;
140 }
Definition: DBUpdater.h:41
template<>
BaseLocation DBUpdater< HotfixDatabaseConnection >::GetBaseLocationType ( )
197 {
198  return LOCATION_DOWNLOAD;
199 }
Definition: DBUpdater.h:41
template<class T >
static std::string DBUpdater< T >::GetConfigEntry ( )
inlinestatic
template<>
std::string DBUpdater< LoginDatabaseConnection >::GetConfigEntry ( )
86 {
87  return "Updates.Auth";
88 }
template<>
std::string DBUpdater< WorldDatabaseConnection >::GetConfigEntry ( )
113 {
114  return "Updates.World";
115 }
template<>
std::string DBUpdater< CharacterDatabaseConnection >::GetConfigEntry ( )
145 {
146  return "Updates.Character";
147 }
template<>
std::string DBUpdater< HotfixDatabaseConnection >::GetConfigEntry ( )
172 {
173  return "Updates.Hotfix";
174 }
template<class T >
static std::string DBUpdater< T >::GetTableName ( )
inlinestatic
template<>
std::string DBUpdater< LoginDatabaseConnection >::GetTableName ( )
92 {
93  return "Auth";
94 }
template<>
std::string DBUpdater< WorldDatabaseConnection >::GetTableName ( )
119 {
120  return "World";
121 }
template<>
std::string DBUpdater< CharacterDatabaseConnection >::GetTableName ( )
151 {
152  return "Character";
153 }
template<>
std::string DBUpdater< HotfixDatabaseConnection >::GetTableName ( )
178 {
179  return "Hotfixes";
180 }
template<class T >
static bool DBUpdater< T >::IsEnabled ( uint32 const  updateMask)
static

+ Here is the caller graph for this function:

template<>
bool DBUpdater< LoginDatabaseConnection >::IsEnabled ( uint32 const  updateMask)
105 {
106  // This way silences warnings under msvc
107  return (updateMask & DatabaseLoader::DATABASE_LOGIN) ? true : false;
108 }
Definition: DatabaseLoader.h:46
template<>
bool DBUpdater< WorldDatabaseConnection >::IsEnabled ( uint32 const  updateMask)
131 {
132  // This way silences warnings under msvc
133  return (updateMask & DatabaseLoader::DATABASE_WORLD) ? true : false;
134 }
Definition: DatabaseLoader.h:48
template<>
bool DBUpdater< CharacterDatabaseConnection >::IsEnabled ( uint32 const  updateMask)
164 {
165  // This way silences warnings under msvc
166  return (updateMask & DatabaseLoader::DATABASE_CHARACTER) ? true : false;
167 }
Definition: DatabaseLoader.h:47
template<>
bool DBUpdater< HotfixDatabaseConnection >::IsEnabled ( uint32 const  updateMask)
190 {
191  // This way silences warnings under msvc
192  return (updateMask & DatabaseLoader::DATABASE_HOTFIX) ? true : false;
193 }
Definition: DatabaseLoader.h:49
template<class T >
bool DBUpdater< T >::Populate ( DatabaseWorkerPool< T > &  pool)
static
300 {
301  {
302  QueryResult const result = Retrieve(pool, "SHOW TABLES");
303  if (result && (result->GetRowCount() > 0))
304  return true;
305  }
306 
308  return false;
309 
310  TC_LOG_INFO("sql.updates", "Database %s is empty, auto populating it...", DBUpdater<T>::GetTableName().c_str());
311 
312  std::string const p = DBUpdater<T>::GetBaseFile();
313  if (p.empty())
314  {
315  TC_LOG_INFO("sql.updates", ">> No base file provided, skipped!");
316  return true;
317  }
318 
319  Path const base(p);
320  if (!exists(base))
321  {
323  {
324  case LOCATION_REPOSITORY:
325  {
326  TC_LOG_ERROR("sql.updates", ">> Base file \"%s\" is missing, try to clone the source again.",
327  base.generic_string().c_str());
328 
329  break;
330  }
331  case LOCATION_DOWNLOAD:
332  {
333  TC_LOG_ERROR("sql.updates", ">> File \"%s\" is missing, download it from \"https://github.com/TrinityCore/TrinityCore/releases\"" \
334  " and place it in your server directory.", base.filename().generic_string().c_str());
335  break;
336  }
337  }
338  return false;
339  }
340 
341  // Update database
342  TC_LOG_INFO("sql.updates", ">> Applying \'%s\'...", base.generic_string().c_str());
343  try
344  {
345  ApplyFile(pool, base);
346  }
347  catch (UpdateException&)
348  {
349  return false;
350  }
351 
352  TC_LOG_INFO("sql.updates", ">> Done!");
353  return true;
354 }
Definition: DBUpdater.h:41
Definition: DBUpdater.h:26
static std::string GetBaseFile()
Definition: DBUpdater.h:40
static bool CheckExecutable()
Definition: DBUpdater.cpp:47
boost::filesystem::path Path
Definition: DBUpdater.h:72
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
Definition: DBUpdater.h:69
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
static QueryResult Retrieve(DatabaseWorkerPool< T > &pool, std::string const &query)
Definition: DBUpdater.cpp:357
static void ApplyFile(DatabaseWorkerPool< T > &pool, Path const &path)
Definition: DBUpdater.cpp:369

+ Here is the call graph for this function:

template<class T >
QueryResult DBUpdater< T >::Retrieve ( DatabaseWorkerPool< T > &  pool,
std::string const query 
)
staticprivate
358 {
359  return pool.PQuery(query.c_str());
360 }
QueryResult PQuery(Format &&sql, T *conn, Args &&...args)
Definition: DatabaseWorkerPool.h:165
char * query(struct soap *soap)
Definition: httpget.cpp:244

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T >
bool DBUpdater< T >::Update ( DatabaseWorkerPool< T > &  pool)
static
255 {
257  return false;
258 
259  TC_LOG_INFO("sql.updates", "Updating %s database...", DBUpdater<T>::GetTableName().c_str());
260 
261  Path const sourceDirectory(BuiltInConfig::GetSourceDirectory());
262 
263  if (!is_directory(sourceDirectory))
264  {
265  TC_LOG_ERROR("sql.updates", "DBUpdater: Given source directory %s does not exist, skipped!", sourceDirectory.generic_string().c_str());
266  return false;
267  }
268 
269  UpdateFetcher updateFetcher(sourceDirectory, [&](std::string const& query) { DBUpdater<T>::Apply(pool, query); },
270  [&](Path const& file) { DBUpdater<T>::ApplyFile(pool, file); },
271  [&](std::string const& query) -> QueryResult { return DBUpdater<T>::Retrieve(pool, query); });
272 
273  UpdateResult result;
274  try
275  {
276  result = updateFetcher.Update(
277  sConfigMgr->GetBoolDefault("Updates.Redundancy", true),
278  sConfigMgr->GetBoolDefault("Updates.AllowRehash", true),
279  sConfigMgr->GetBoolDefault("Updates.ArchivedRedundancy", false),
280  sConfigMgr->GetIntDefault("Updates.CleanDeadRefMaxCount", 3));
281  }
282  catch (UpdateException&)
283  {
284  return false;
285  }
286 
287  std::string const info = Trinity::StringFormat("Containing " SZFMTD " new and " SZFMTD " archived updates.",
288  result.recent, result.archived);
289 
290  if (!result.updated)
291  TC_LOG_INFO("sql.updates", ">> %s database is up-to-date! %s", DBUpdater<T>::GetTableName().c_str(), info.c_str());
292  else
293  TC_LOG_INFO("sql.updates", ">> Applied " SZFMTD " %s. %s", result.updated, result.updated == 1 ? "query" : "queries", info.c_str());
294 
295  return true;
296 }
Definition: DBUpdater.h:26
TC_COMMON_API std::string GetSourceDirectory()
Definition: BuiltInConfig.cpp:42
#define SZFMTD
Definition: Define.h:143
#define sConfigMgr
Definition: Config.h:61
char * query(struct soap *soap)
Definition: httpget.cpp:244
static void Apply(DatabaseWorkerPool< T > &pool, std::string const &query)
Definition: DBUpdater.cpp:363
static bool CheckExecutable()
Definition: DBUpdater.cpp:47
Definition: DBUpdater.h:44
boost::filesystem::path Path
Definition: DBUpdater.h:72
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
std::string StringFormat(Format &&fmt, Args &&...args)
Default TC string format function.
Definition: StringFormat.h:28
Definition: DBUpdater.h:69
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
Definition: UpdateFetcher.h:28
static QueryResult Retrieve(DatabaseWorkerPool< T > &pool, std::string const &query)
Definition: DBUpdater.cpp:357
static void ApplyFile(DatabaseWorkerPool< T > &pool, Path const &path)
Definition: DBUpdater.cpp:369

+ Here is the call graph for this function:


The documentation for this class was generated from the following files: