AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
DBUpdater< T > Class Template Reference

#include "DBUpdater.h"

Public Types

using Path = std::filesystem::path
 

Public Member Functions

std::string GetConfigEntry ()
 
std::string GetTableName ()
 
std::string GetBaseFilesDirectory ()
 
bool IsEnabled (uint32 const updateMask)
 
std::string GetDBModuleName ()
 
std::string GetConfigEntry ()
 
std::string GetTableName ()
 
std::string GetBaseFilesDirectory ()
 
bool IsEnabled (uint32 const updateMask)
 
std::string GetDBModuleName ()
 
std::string GetConfigEntry ()
 
std::string GetTableName ()
 
std::string GetBaseFilesDirectory ()
 
bool IsEnabled (uint32 const updateMask)
 
std::string GetDBModuleName ()
 

Static Public Member Functions

static std::string GetConfigEntry ()
 
static std::string GetTableName ()
 
static std::string GetBaseFilesDirectory ()
 
static bool IsEnabled (uint32 const updateMask)
 
static BaseLocation GetBaseLocationType ()
 
static bool Create (DatabaseWorkerPool< T > &pool)
 
static bool Update (DatabaseWorkerPool< T > &pool, std::string_view modulesList={})
 
static bool Update (DatabaseWorkerPool< T > &pool, std::vector< std::string > const *setDirectories)
 
static bool Populate (DatabaseWorkerPool< T > &pool)
 
static std::string GetDBModuleName ()
 

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, std::string const &ssl, Path const &path)
 

Detailed Description

template<class T>
class DBUpdater< T >

Member Typedef Documentation

◆ Path

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

Member Function Documentation

◆ Apply()

template<class T >
void DBUpdater< T >::Apply ( DatabaseWorkerPool< T > &  pool,
std::string const &  query 
)
staticprivate
456{
457 pool.DirectExecute(query.c_str());
458}
void DirectExecute(std::string_view sql)
Definition DatabaseWorkerPool.cpp:532

References DatabaseWorkerPool< T >::DirectExecute().

Referenced by DBUpdater< T >::Update(), and DBUpdater< T >::Update().

◆ ApplyFile() [1/2]

template<class T >
void DBUpdater< T >::ApplyFile ( DatabaseWorkerPool< T > &  pool,
Path const &  path 
)
staticprivate
462{
465}
static void ApplyFile(DatabaseWorkerPool< T > &pool, Path const &path)
Definition DBUpdater.cpp:461
MySQLConnectionInfo const * GetConnectionInfo() const
Definition DatabaseWorkerPool.h:71
std::string host
Definition MySQLConnection.h:49
std::string port_or_socket
Definition MySQLConnection.h:50
std::string user
Definition MySQLConnection.h:46
std::string database
Definition MySQLConnection.h:48
std::string ssl
Definition MySQLConnection.h:51
std::string password
Definition MySQLConnection.h:47

References DBUpdater< T >::ApplyFile(), MySQLConnectionInfo::database, DatabaseWorkerPool< T >::GetConnectionInfo(), MySQLConnectionInfo::host, MySQLConnectionInfo::password, MySQLConnectionInfo::port_or_socket, MySQLConnectionInfo::ssl, and MySQLConnectionInfo::user.

Referenced by DBUpdater< T >::ApplyFile(), DBUpdater< T >::Create(), DBUpdater< T >::Update(), and DBUpdater< T >::Update().

◆ ApplyFile() [2/2]

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,
std::string const &  ssl,
Path const &  path 
)
staticprivate
470{
471 std::string configTempDir = sConfigMgr->GetOption<std::string>("TempDir", "");
472
473 auto tempDir = configTempDir.empty() ? std::filesystem::temp_directory_path().string() : configTempDir;
474
475 tempDir = Acore::String::AddSuffixIfNotExists(tempDir, std::filesystem::path::preferred_separator);
476
477 std::string confFileName = "mysql_ac.conf";
478
479 std::ofstream outfile (tempDir + confFileName);
480
481 outfile << "[client]\npassword = \"" << password << '"' << std::endl;
482
483 outfile.close();
484
485 std::vector<std::string> args;
486 args.reserve(9);
487
488 args.emplace_back("--defaults-extra-file="+tempDir + confFileName+"");
489
490 // CLI Client connection info
491 args.emplace_back("-h" + host);
492 args.emplace_back("-u" + user);
493
494 // Check if we want to connect through ip or socket (Unix only)
495#ifdef _WIN32
496
497 if (host == ".")
498 args.emplace_back("--protocol=PIPE");
499 else
500 args.emplace_back("-P" + port_or_socket);
501
502#else
503
504 if (!std::isdigit(port_or_socket[0]))
505 {
506 // We can't check if host == "." here, because it is named localhost if socket option is enabled
507 args.emplace_back("-P0");
508 args.emplace_back("--protocol=SOCKET");
509 args.emplace_back("-S" + port_or_socket);
510 }
511 else
512 // generic case
513 args.emplace_back("-P" + port_or_socket);
514
515#endif
516
517 // Set the default charset to utf8
518 args.emplace_back("--default-character-set=utf8");
519
520 // Set max allowed packet to 1 GB
521 args.emplace_back("--max-allowed-packet=1GB");
522
523 if (ssl == "ssl")
524 args.emplace_back("--ssl-mode=REQUIRED");
525
526 // Database
527 if (!database.empty())
528 args.emplace_back(database);
529
530 // Invokes a mysql process which doesn't leak credentials to logs
532 "sql.updates", path.generic_string(), true);
533
534 if (ret != EXIT_SUCCESS)
535 {
536 LOG_FATAL("sql.updates", "Applying of file \'{}\' to database \'{}\' failed!" \
537 " If you are a user, please pull the latest revision from the repository. "
538 "Also make sure you have not applied any of the databases with your sql client. "
539 "You cannot use auto-update system and import sql files from AzerothCore repository with your sql client. "
540 "If you are a developer, please fix your sql query.",
541 path.generic_string(), pool.GetConnectionInfo()->database);
542
543 // Recorded in both modes. A dry run does not throw below, so it keeps attempting the
544 // remaining files and this count is the only thing left to fail the run on.
546
547 if (!sConfigMgr->isDryRun())
548 {
549 if (uint32 delay = sConfigMgr->GetOption<uint32>("Updates.ExceptionShutdownDelay", 10000))
550 std::this_thread::sleep_for(Milliseconds(delay));
551
552 throw UpdateException("update failed");
553 }
554 }
555}
std::uint32_t uint32
Definition Define.h:107
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
#define LOG_FATAL(filterType__,...)
Definition Log.h:141
static std::string GetCorrectedMySQLExecutable()
Definition DBUpdater.cpp:32
static void MarkUpdateFailed()
Definition DBUpdater.cpp:73
Definition DBUpdater.h:39
#define sConfigMgr
Definition Config.h:93
AC_COMMON_API std::string AddSuffixIfNotExists(std::string str, const char suffix)
Util function to add a suffix char. Can be used to add a slash at the end of a path.
Definition StringFormat.cpp:73
int StartProcess(std::string const &executable, std::vector< std::string > const &args, std::string const &logger, std::string input_file, bool secure)
Definition StartProcess.cpp:169

References Acore::String::AddSuffixIfNotExists(), MySQLConnectionInfo::database, DatabaseWorkerPool< T >::GetConnectionInfo(), DBUpdaterUtil::GetCorrectedMySQLExecutable(), LOG_FATAL, DBUpdaterUtil::MarkUpdateFailed(), sConfigMgr, and Acore::StartProcess().

◆ Create()

template<class T >
bool DBUpdater< T >::Create ( DatabaseWorkerPool< T > &  pool)
static
191{
192 LOG_WARN("sql.updates", "Database \"{}\" does not exist", pool.GetConnectionInfo()->database);
193
194 char const* disableInteractive = std::getenv("AC_DISABLE_INTERACTIVE");
195
196 if (!sConfigMgr->isDryRun() && (disableInteractive == nullptr || std::strcmp(disableInteractive, "1") != 0))
197 {
198 std::cout << "Do you want to create it? [yes (default) / no]:" << std::endl;
199 std::string answer;
200 std::getline(std::cin, answer);
201 if (!answer.empty() && !(answer.substr(0, 1) == "y"))
202 return false;
203 }
204
205 LOG_INFO("sql.updates", "Creating database \"{}\"...", pool.GetConnectionInfo()->database);
206
207 // Path of temp file
208 static Path const temp("create_table.sql");
209
210 // Create temporary query to use external MySQL CLi
211 std::ofstream file(temp.generic_string());
212 if (!file.is_open())
213 {
214 LOG_FATAL("sql.updates", "Failed to create temporary query file \"{}\"!", temp.generic_string());
215 return false;
216 }
217
218 file << "CREATE DATABASE `" << pool.GetConnectionInfo()->database << "` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_general_ci;\n\n";
219 file.close();
220
221 try
222 {
224 pool.GetConnectionInfo()->port_or_socket, "", pool.GetConnectionInfo()->ssl, temp);
225 }
226 catch (UpdateException&)
227 {
228 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);
229 std::filesystem::remove(temp);
230 return false;
231 }
232
233 LOG_INFO("sql.updates", "Done.");
234 LOG_INFO("sql.updates", " ");
235 std::filesystem::remove(temp);
236 return true;
237}
#define LOG_INFO(filterType__,...)
Definition Log.h:153
#define LOG_WARN(filterType__,...)
Definition Log.h:149
std::filesystem::path Path
Definition DBUpdater.h:78

References DBUpdater< T >::ApplyFile(), MySQLConnectionInfo::database, DatabaseWorkerPool< T >::GetConnectionInfo(), MySQLConnectionInfo::host, LOG_FATAL, LOG_INFO, LOG_WARN, MySQLConnectionInfo::password, MySQLConnectionInfo::port_or_socket, sConfigMgr, MySQLConnectionInfo::ssl, and MySQLConnectionInfo::user.

◆ GetBaseFilesDirectory() [1/4]

std::string DBUpdater< LoginDatabaseConnection >::GetBaseFilesDirectory ( )
98{
99 return BuiltInConfig::GetSourceDirectory() + "/data/sql/base/db_auth/";
100}
AC_COMMON_API std::string GetSourceDirectory()
Definition BuiltInConfig.cpp:42

References BuiltInConfig::GetSourceDirectory().

◆ GetBaseFilesDirectory() [2/4]

std::string DBUpdater< WorldDatabaseConnection >::GetBaseFilesDirectory ( )
131{
132 return BuiltInConfig::GetSourceDirectory() + "/data/sql/base/db_world/";
133}

References BuiltInConfig::GetSourceDirectory().

◆ GetBaseFilesDirectory() [3/4]

std::string DBUpdater< CharacterDatabaseConnection >::GetBaseFilesDirectory ( )
164{
165 return BuiltInConfig::GetSourceDirectory() + "/data/sql/base/db_characters/";
166}

References BuiltInConfig::GetSourceDirectory().

◆ GetBaseFilesDirectory() [4/4]

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

◆ GetBaseLocationType()

template<class T >
BaseLocation DBUpdater< T >::GetBaseLocationType ( )
static
185{
186 return LOCATION_REPOSITORY;
187}
@ LOCATION_REPOSITORY
Definition DBUpdater.h:52

References LOCATION_REPOSITORY.

◆ GetConfigEntry() [1/4]

std::string DBUpdater< LoginDatabaseConnection >::GetConfigEntry ( )
86{
87 return "Updates.Auth";
88}

◆ GetConfigEntry() [2/4]

std::string DBUpdater< WorldDatabaseConnection >::GetConfigEntry ( )
119{
120 return "Updates.World";
121}

◆ GetConfigEntry() [3/4]

std::string DBUpdater< CharacterDatabaseConnection >::GetConfigEntry ( )
152{
153 return "Updates.Character";
154}

◆ GetConfigEntry() [4/4]

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

◆ GetDBModuleName() [1/4]

std::string DBUpdater< LoginDatabaseConnection >::GetDBModuleName ( )
111{
112 // must be lowercase
113 return "auth";
114}

◆ GetDBModuleName() [2/4]

std::string DBUpdater< WorldDatabaseConnection >::GetDBModuleName ( )
144{
145 // must be lowercase
146 return "world";
147}

◆ GetDBModuleName() [3/4]

std::string DBUpdater< CharacterDatabaseConnection >::GetDBModuleName ( )
177{
178 // must be lowercase
179 return "characters";
180}

◆ GetDBModuleName() [4/4]

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

◆ GetTableName() [1/4]

std::string DBUpdater< LoginDatabaseConnection >::GetTableName ( )
92{
93 return "Auth";
94}

◆ GetTableName() [2/4]

std::string DBUpdater< WorldDatabaseConnection >::GetTableName ( )
125{
126 return "World";
127}

◆ GetTableName() [3/4]

std::string DBUpdater< CharacterDatabaseConnection >::GetTableName ( )
158{
159 return "Character";
160}

◆ GetTableName() [4/4]

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

◆ IsEnabled() [1/4]

bool DBUpdater< LoginDatabaseConnection >::IsEnabled ( uint32 const  updateMask)
104{
105 // This way silences warnings under msvc
106 return (updateMask & DatabaseLoader::DATABASE_LOGIN) ? true : false;
107}
@ DATABASE_LOGIN
Definition DatabaseLoader.h:48

References DatabaseLoader::DATABASE_LOGIN.

◆ IsEnabled() [2/4]

bool DBUpdater< WorldDatabaseConnection >::IsEnabled ( uint32 const  updateMask)
137{
138 // This way silences warnings under msvc
139 return (updateMask & DatabaseLoader::DATABASE_WORLD) ? true : false;
140}
@ DATABASE_WORLD
Definition DatabaseLoader.h:50

References DatabaseLoader::DATABASE_WORLD.

◆ IsEnabled() [3/4]

bool DBUpdater< CharacterDatabaseConnection >::IsEnabled ( uint32 const  updateMask)
170{
171 // This way silences warnings under msvc
172 return (updateMask & DatabaseLoader::DATABASE_CHARACTER) ? true : false;
173}
@ DATABASE_CHARACTER
Definition DatabaseLoader.h:49

References DatabaseLoader::DATABASE_CHARACTER.

◆ IsEnabled() [4/4]

template<class T >
static bool DBUpdater< T >::IsEnabled ( uint32 const  updateMask)
static

◆ Populate()

template<class T >
bool DBUpdater< T >::Populate ( DatabaseWorkerPool< T > &  pool)
static
377{
378 {
379 QueryResult const result = Retrieve(pool, "SHOW TABLES");
380 if (result && (result->GetRowCount() > 0))
381 return true;
382 }
383
385 return false;
386
387 LOG_INFO("sql.updates", "Database {} is empty, auto populating it...", DBUpdater<T>::GetTableName());
388
389 std::string const DirPathStr = DBUpdater<T>::GetBaseFilesDirectory();
390
391 Path const DirPath(DirPathStr);
392 if (!std::filesystem::is_directory(DirPath))
393 {
394 LOG_ERROR("sql.updates", ">> Directory \"{}\" not exist", DirPath.generic_string());
395 return false;
396 }
397
398 if (DirPath.empty())
399 {
400 LOG_ERROR("sql.updates", ">> Directory \"{}\" is empty", DirPath.generic_string());
401 return false;
402 }
403
404 std::filesystem::directory_iterator const DirItr;
405 uint32 FilesCount = 0;
406
407 for (std::filesystem::directory_iterator itr(DirPath); itr != DirItr; ++itr)
408 {
409 if (itr->path().extension() == ".sql")
410 FilesCount++;
411 }
412
413 if (!FilesCount)
414 {
415 LOG_ERROR("sql.updates", ">> In directory \"{}\" not exist '*.sql' files", DirPath.generic_string());
416 return false;
417 }
418
419 std::vector<std::filesystem::path> sqlFiles;
420
421 for (auto const& entry : std::filesystem::directory_iterator(DirPath))
422 {
423 if (entry.path().extension() == ".sql")
424 sqlFiles.push_back(entry.path());
425 }
426
427 std::sort(sqlFiles.begin(), sqlFiles.end());
428
429 for (auto const& file : sqlFiles)
430 {
431 LOG_INFO("sql.updates", ">> Applying \'{}\'...", file.filename().generic_string());
432
433 try
434 {
435 ApplyFile(pool, file);
436 }
437 catch (UpdateException&)
438 {
439 return false;
440 }
441 }
442
443 LOG_INFO("sql.updates", ">> Done!");
444 LOG_INFO("sql.updates", " ");
445 return true;
446}
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
static bool CheckExecutable()
Definition DBUpdater.cpp:40
Definition DBUpdater.h:76
static QueryResult Retrieve(DatabaseWorkerPool< T > &pool, std::string const &query)
Definition DBUpdater.cpp:449
static std::string GetBaseFilesDirectory()
STL namespace.

References DBUpdaterUtil::CheckExecutable(), DBUpdater< T >::GetBaseFilesDirectory(), LOG_ERROR, and LOG_INFO.

◆ Retrieve()

template<class T >
QueryResult DBUpdater< T >::Retrieve ( DatabaseWorkerPool< T > &  pool,
std::string const &  query 
)
staticprivate
450{
451 return pool.Query(query.c_str());
452}
QueryResult Query(std::string_view sql)
Definition DatabaseWorkerPool.cpp:181

References DatabaseWorkerPool< T >::Query().

Referenced by DBUpdater< T >::Update(), and DBUpdater< T >::Update().

◆ Update() [1/2]

template<class T >
bool DBUpdater< T >::Update ( DatabaseWorkerPool< T > &  pool,
std::string_view  modulesList = {} 
)
static
241{
243 return false;
244
245 LOG_INFO("sql.updates", "Updating {} database...", DBUpdater<T>::GetTableName());
246
247 Path const sourceDirectory(BuiltInConfig::GetSourceDirectory());
248
249 if (!is_directory(sourceDirectory))
250 {
251 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\\azerothcore). Shutting down.",
252 sourceDirectory.generic_string());
253 return false;
254 }
255
256 auto CheckUpdateTable = [&](std::string const& tableName)
257 {
258 auto checkTable = DBUpdater<T>::Retrieve(pool, Acore::StringFormat("SHOW TABLES LIKE '{}'", tableName));
259 if (!checkTable)
260 {
261 LOG_WARN("sql.updates", "> Table '{}' not exist! Try add based table", tableName);
262
263 Path const temp(GetBaseFilesDirectory() + tableName + ".sql");
264
265 try
266 {
267 DBUpdater<T>::ApplyFile(pool, temp);
268 }
269 catch (UpdateException&)
270 {
271 LOG_FATAL("sql.updates", "Failed apply file to database {}! Does the user (named in *.conf) have `INSERT` and `DELETE` privileges on the MySQL server?", pool.GetConnectionInfo()->database);
272 return false;
273 }
274
275 return true;
276 }
277
278 return true;
279 };
280
281 if (!CheckUpdateTable("updates") || !CheckUpdateTable("updates_include"))
282 return false;
283
284 UpdateFetcher updateFetcher(sourceDirectory, [&](std::string const & query) { DBUpdater<T>::Apply(pool, query); },
285 [&](Path const & file) { DBUpdater<T>::ApplyFile(pool, file); },
286 [&](std::string const & query) -> QueryResult { return DBUpdater<T>::Retrieve(pool, query); }, DBUpdater<T>::GetDBModuleName(), modulesList);
287
288 UpdateResult result;
289 try
290 {
291 result = updateFetcher.Update(
292 sConfigMgr->GetOption<bool>("Updates.Redundancy", true),
293 sConfigMgr->GetOption<bool>("Updates.AllowRehash", true),
294 sConfigMgr->GetOption<bool>("Updates.ArchivedRedundancy", false),
295 sConfigMgr->GetOption<int32>("Updates.CleanDeadRefMaxCount", 3));
296 }
297 catch (UpdateException&)
298 {
299 return false;
300 }
301
302 std::string const info = Acore::StringFormat("Containing {} new and {} archived updates.", result.recent, result.archived);
303
304 if (!result.updated)
305 LOG_INFO("sql.updates", ">> {} database is up-to-date! {}", DBUpdater<T>::GetTableName(), info);
306 else
307 LOG_INFO("sql.updates", ">> Applied {} {}. {}", result.updated, result.updated == 1 ? "query" : "queries", info);
308
309 LOG_INFO("sql.updates", " ");
310
311 return true;
312}
std::int32_t int32
Definition Define.h:103
static void Apply(DatabaseWorkerPool< T > &pool, std::string const &query)
Definition DBUpdater.cpp:455
static std::string GetDBModuleName()
Definition UpdateFetcher.h:43
std::string StringFormat(FormatStringView fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:44
Definition UpdateFetcher.h:30

References DBUpdater< T >::Apply(), DBUpdater< T >::ApplyFile(), DBUpdaterUtil::CheckExecutable(), MySQLConnectionInfo::database, DatabaseWorkerPool< T >::GetConnectionInfo(), DBUpdater< T >::GetDBModuleName(), BuiltInConfig::GetSourceDirectory(), LOG_ERROR, LOG_FATAL, LOG_INFO, LOG_WARN, DBUpdater< T >::Retrieve(), sConfigMgr, and Acore::StringFormat().

◆ Update() [2/2]

template<class T >
bool DBUpdater< T >::Update ( DatabaseWorkerPool< T > &  pool,
std::vector< std::string > const *  setDirectories 
)
static
316{
318 {
319 return false;
320 }
321
322 Path const sourceDirectory(BuiltInConfig::GetSourceDirectory());
323 if (!is_directory(sourceDirectory))
324 {
325 return false;
326 }
327
328 auto CheckUpdateTable = [&](std::string const& tableName)
329 {
330 auto checkTable = DBUpdater<T>::Retrieve(pool, Acore::StringFormat("SHOW TABLES LIKE '{}'", tableName));
331 if (!checkTable)
332 {
333 Path const temp(GetBaseFilesDirectory() + tableName + ".sql");
334 try
335 {
336 DBUpdater<T>::ApplyFile(pool, temp);
337 }
338 catch (UpdateException&)
339 {
340 return false;
341 }
342
343 return true;
344 }
345
346 return true;
347 };
348
349 if (!CheckUpdateTable("updates") || !CheckUpdateTable("updates_include"))
350 {
351 return false;
352 }
353
354 UpdateFetcher updateFetcher(sourceDirectory, [&](std::string const & query) { DBUpdater<T>::Apply(pool, query); },
355 [&](Path const & file) { DBUpdater<T>::ApplyFile(pool, file); },
356 [&](std::string const & query) -> QueryResult { return DBUpdater<T>::Retrieve(pool, query); }, DBUpdater<T>::GetDBModuleName(), setDirectories);
357
358 UpdateResult result;
359 try
360 {
361 result = updateFetcher.Update(
362 sConfigMgr->GetOption<bool>("Updates.Redundancy", true),
363 sConfigMgr->GetOption<bool>("Updates.AllowRehash", true),
364 sConfigMgr->GetOption<bool>("Updates.ArchivedRedundancy", false),
365 sConfigMgr->GetOption<int32>("Updates.CleanDeadRefMaxCount", 3));
366 }
367 catch (UpdateException&)
368 {
369 return false;
370 }
371
372 return true;
373}

References DBUpdater< T >::Apply(), DBUpdater< T >::ApplyFile(), DBUpdaterUtil::CheckExecutable(), DBUpdater< T >::GetDBModuleName(), BuiltInConfig::GetSourceDirectory(), DBUpdater< T >::Retrieve(), sConfigMgr, and Acore::StringFormat().


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