36 #define COLUMN_BOUNDS_CHECKING
39 #define sProfiler ( Profiler::get() )
57 mysql = mysql_init(
nullptr);
62 sLog.Cyan(
" DB User",
" %s",
pUser.c_str());
67 enum mysql_protocol_type prot_type = MYSQL_PROTOCOL_SOCKET;
68 if (mysql_options(
mysql, MYSQL_OPT_PROTOCOL, (
void*)&prot_type) == 0) {
69 sLog.Cyan(
" DB Server",
" Unix Socket Connection");
71 sLog.Error(
" DB Server",
" Unix Socket Connection Option Failed");
72 enum mysql_protocol_type prot_type = MYSQL_PROTOCOL_TCP;
73 if (mysql_options(
mysql, MYSQL_OPT_PROTOCOL, (
void*)&prot_type) == 0)
76 sLog.Error(
" DB Server",
" TCP Connection Option Failed");
79 enum mysql_protocol_type prot_type = MYSQL_PROTOCOL_TCP;
80 if (mysql_options(
mysql, MYSQL_OPT_PROTOCOL, (
void*)&prot_type) == 0)
83 sLog.Error(
" DB Server",
" TCP Connection Option Failed");
86 int32 flags = CLIENT_FOUND_ROWS;
88 flags |= CLIENT_COMPRESS;
92 sLog.Cyan(
" Connect Flags",
" %x", flags);
109 my_bool reconnect =
true;
110 if (mysql_options(
mysql, MYSQL_OPT_RECONNECT, (
void*)&reconnect) == 0)
111 sLog.Green(
" DataBase Manager",
"DataBase AutoReconnect Enabled");
113 sLog.Error(
" DataBase Manager",
"DataBase AutoReconnect Option Failed");
115 sLog.Yellow(
" DataBase Manager",
"DataBase AutoReconnect Disabled");
119 *errnum = mysql_errno(
mysql);
120 if (errbuf !=
nullptr)
121 snprintf(errbuf, MYSQL_ERRMSG_SIZE,
"#%i: %s", mysql_errno(
mysql), mysql_error(
mysql));
124 sLog.Error(
" ServerInit",
"Unable to connect to the database: %s", err.
c_str() );
129 sLog.Blue(
" DataBase Manager",
"DataBase Connected");
133 if (mysql_set_character_set(
mysql,
"utf8") == 0)
134 sLog.Cyan(
" DataBase Manager",
"DataBase Character set: %s", mysql_character_set_name(
mysql));
139 _log(DATABASE__MESSAGE,
"DBCore attempting to recover...");
141 mysql = mysql_init(
nullptr);
149 _log(DATABASE__MESSAGE,
"DBCore recovery successful. Continuing.");
154 void DBcore::Initialize(std::string host, std::string user, std::string password, std::string database,
bool compress,
155 bool SSL,
int16 port,
bool socket,
bool reconnect,
bool profile)
157 if (
mysql ==
nullptr)
158 mysql = mysql_init(
nullptr);
159 if (
mysql ==
nullptr) {
160 sLog.Error(
" ServerInit",
"Unable to connect to the database: mysql_init returned null");
178 sLog.Error(
" ServerInit",
"Unable to connect to the database: required connect field(s) are empty.");
189 sLog.Blue(
" DataBase Manager",
"DataBase Manager Initialized");
227 va_start(vlist, query_fmt);
234 uint col_count = mysql_field_count(
mysql);
235 if (col_count == 0) {
237 codelog(DATABASE__ERROR,
"DBCore::RunQuery: %s failed because it did not return a result", query);
252 va_start(args, query_fmt);
253 char* query(
nullptr);
254 int querylen =
vasprintf(&query, query_fmt, args);
271 va_start(args, query_fmt);
272 char* query(
nullptr);
273 int querylen =
vasprintf(&query, query_fmt, args);
282 affected_rows = (
uint32)mysql_affected_rows(
mysql);
292 va_start(args, query_fmt);
293 char* query(
nullptr);
294 int querylen =
vasprintf(&query, query_fmt, args);
312 if (
mysql ==
nullptr) {
314 codelog(DATABASE__ERROR,
"DBCore - mysql = null");
320 codelog(DATABASE__ERROR,
"DBCore - Status != Connected");
321 _log(DATABASE__MESSAGE,
"DBCore error detected. Look for error msgs in logs prior to this point.");
327 _log(DATABASE__QUERIES,
"DBcore Query - %s", query);
329 if (mysql_real_query(
mysql, query, querylen)) {
330 uint num = mysql_errno(
mysql);
335 if ((num == CR_SERVER_LOST) or (num == CR_SERVER_GONE_ERROR)) {
336 _log(DATABASE__ERROR,
"DBCore error - server lost or gone.");
360 return mysql_real_escape_string(
mysql, tobuf, frombuf, fromlen);
368 uint32 esc_len = mysql_real_escape_string(
mysql, &to[0], from.c_str(), len);
369 to.resize(esc_len + 1);
374 for(; *str !=
'\0'; str++) {
385 for (uint i = 0; i < s.length(); ++i) {
428 std::string errStr =
"No Error";
528 return ((
mFields[index]->flags & UNSIGNED_FLAG) == UNSIGNED_FLAG);
535 return (
mFields[index]->charsetnr == 63);
557 MYSQL_ROW row = mysql_fetch_row(
mResult );
561 const ulong* lengths = mysql_fetch_lengths(
mResult );
562 if (lengths ==
nullptr)
565 into.
SetData(
this, row, lengths );
572 _log(DATABASE__ERROR,
"DBCore ColumnName: Column index %d exceeds number of columns in row (%s)\n", index,
mColumnCount );
583 _log(DATABASE__ERROR,
"DBCore ColumnType: Column index %d exceeds number of columns in row (%s)\n", index,
mColumnCount );
590 if ( columnType > MYSQL_TYPE_BIT )
597 if (IS_NUM(columnType))
627 _log(DATABASE__ERROR,
" DBCore::GetColumnLength: Column index %u exceeds number of columns in row (%u)", index,
mResult->
ColumnCount() );
638 _log(DATABASE__ERROR,
" DBCore::GetInt: Column index %u exceeds number of columns in row (%u)", index,
mResult->
ColumnCount() );
644 return strtol(
mRow[index],
nullptr, 0 );
650 _log(DATABASE__ERROR,
" DBCore::GetBool: Column index %u exceeds number of columns in row (%u)", index,
mResult->
ColumnCount() );
655 return (
mRow[index][0] != 0);
661 _log(DATABASE__ERROR,
" DBCore::GetUInt: Column index %u exceeds number of columns in row (%u)", index,
mResult->
ColumnCount() );
667 return strtoul(
mRow[index],
nullptr, 0 );
673 _log(DATABASE__ERROR,
" DBCore::GetInt64: Column index %u exceeds number of columns in row (%u)", index,
mResult->
ColumnCount() );
685 _log(DATABASE__ERROR,
" DBCore::GetFloat: Column index %u exceeds number of columns in row (%u)", index,
mResult->
ColumnCount() );
696 _log(DATABASE__ERROR,
" DBCore::GetDouble: Column index %u exceeds number of columns in row (%u)", index,
mResult->
ColumnCount() );
701 return strtod(
mRow[index],
nullptr );
static const DBTYPE MYSQL_DBTYPE_TABLE_UNSIGNED[]
static const DBTYPE MYSQL_DBTYPE_TABLE_SIGNED[]
bool RunQueryLID(DBerror &err, uint32 &last_insert_id, const char *query_fmt,...)
uint32 ColumnLength(uint32 index) const
bool IsUnsigned(uint32 index) const
void SetData(DBQueryResult *res, MYSQL_ROW &row, const ulong *lengths)
bool TryLock()
Attempts to lock the mutex.
#define _log(type, fmt,...)
float GetFloat(uint32 index) const
int32 GetInt(uint32 index) const
uint32 GetUInt(uint32 index) const
double GetDouble(uint32 index) const
A lock for a Lockable object.
int32 DoEscapeString(char *tobuf, const char *frombuf, int32 fromlen)
bool RunQuery(DBQueryResult &into, const char *query_fmt,...)
void AddTime(uint8 key, double value)
bool DoQuery_locked(DBerror &err, const char *query, int querylen, bool retry=true)
void SetError(uint err, const char *str)
bool GetRow(DBResultRow &into)
bool GetBool(uint32 index) const
int vasprintf(char **strp, const char *fmt, va_list ap)
#define is_log_enabled(type)
#define sLog
Evaluates to a NewLog instance.
const char * c_str() const
uint32 ColumnCount() const
#define codelog(type, fmt,...)
void SetResult(MYSQL_RES *res, uint32 colCount)
bool IsBinary(uint32 index) const
void Unlock()
Unlocks the mutex.
const char * ColumnName(uint32 index) const
float strtof(const char *nptr, char **endptr)
void SafeDeleteArray(T *&p)
Deletes and nullifies an array pointer.
static bool IsSafeString(const char *str)
void Initialize(std::string host, std::string user, std::string password, std::string database, bool compress=false, bool SSL=false, int16 port=3306, bool socket=false, bool reconnect=false, bool profile=false)
Template used for singleton classes.
typeID Spawn an NPC with the specified type text Search for items matching the specified query() type() key(value)-Send an OnRemoteMessage" ) COMMAND( setbpattr
void Connect(uint *errnum=0, char *errbuf=0)
int64 GetInt64(uint32 index) const
DBTYPE ColumnType(uint32 index) const