Skip to content

Commit

Permalink
SQLite: SQLite DB backend support
Browse files Browse the repository at this point in the history
  • Loading branch information
insunaa committed Jan 6, 2024
1 parent 2bcbfc0 commit ab9ce01
Show file tree
Hide file tree
Showing 23 changed files with 728 additions and 31 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Expand Up @@ -251,6 +251,8 @@ endif()
if(UNIX AND (BUILD_GAME_SERVER OR BUILD_LOGIN_SERVER OR BUILD_EXTRACTORS))
if(POSTGRESQL)
find_package(PostgreSQL REQUIRED)
elseif(SQLITE)
find_package(SQLite3 REQUIRED)
else()
find_package(MySQL REQUIRED)
endif()
Expand Down Expand Up @@ -359,6 +361,8 @@ set(DEFINITIONS "")

if(POSTGRESQL)
set(DEFINITIONS ${DEFINITIONS} DO_POSTGRESQL)
elseif(SQLITE)
set(DEFINITIONS ${DEFINITIONS} DO_SQLITE)
else()
set(DEFINITIONS ${DEFINITIONS} DO_MYSQL)
endif()
Expand Down
5 changes: 2 additions & 3 deletions src/game/Accounts/AccountMgr.cpp
Expand Up @@ -56,9 +56,8 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
const char* v_hex = srp.GetVerifier().AsHexStr();

bool update_sv = LoginDatabase.PExecute(
"INSERT INTO account(username,v,s,joindate) VALUES('%s','%s','%s',NOW())",
"INSERT INTO account(username,v,s,joindate) VALUES('%s','%s','%s'," _NOW_ ")",
username.c_str(), v_hex, s_hex);

OPENSSL_free((void*)s_hex);
OPENSSL_free((void*)v_hex);

Expand Down Expand Up @@ -90,7 +89,7 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
const char* v_hex = srp.GetVerifier().AsHexStr();

bool update_sv = LoginDatabase.PExecute(
"INSERT INTO account(username,v,s,joindate,expansion) VALUES('%s','%s','%s',NOW(), %u)",
"INSERT INTO account(username,v,s,joindate,expansion) VALUES('%s','%s','%s'," _NOW_ ",%u)",
username.c_str(), v_hex, s_hex, expansion);

OPENSSL_free((void*)s_hex);
Expand Down
5 changes: 3 additions & 2 deletions src/game/Calendar/Calendar.cpp
Expand Up @@ -18,6 +18,7 @@

#include <utility>
#include "Calendar/Calendar.h"
#include "Database/DatabaseEnv.h"
#include "Mails/Mail.h"
#include "Globals/ObjectMgr.h"
#include "Util/ProgressBar.h"
Expand Down Expand Up @@ -625,7 +626,7 @@ void CalendarMgr::LoadCalendarsFromDB()
// delete all events (no event exist without at least one invite)
m_EventStore.clear();
m_MaxEventId = 0;
CharacterDatabase.DirectExecute("TRUNCATE TABLE calendar_events");
CharacterDatabase.DirectExecute(_TRUNCATE_ " calendar_events");
sLog.outString(">> calendar_invites table is empty, cleared calendar_events table!");
}
else
Expand Down Expand Up @@ -673,7 +674,7 @@ void CalendarMgr::LoadCalendarsFromDB()
else
{
// delete all invites (no invites exist without events)
CharacterDatabase.DirectExecute("TRUNCATE TABLE calendar_invites");
CharacterDatabase.DirectExecute(_TRUNCATE_ " calendar_invites");
sLog.outString(">> calendar_invites table is cleared! (invites without events found)");
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/game/Chat/Level2.cpp
Expand Up @@ -853,7 +853,7 @@ bool ChatHandler::HandleGameObjectTargetCommand(char* args)
uint32 id;
if (ExtractUInt32(&cId, id))
{
queryResult = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND guid = '%u' ORDER BY order_ ASC LIMIT 1",
queryResult = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject WHERE map = '%i' AND guid = '%u' ORDER BY order_ ASC LIMIT 1",
pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(), id);
}
else
Expand Down Expand Up @@ -1253,8 +1253,8 @@ bool ChatHandler::HandleGameObjectNearCommand(char* args)

Player* pl = m_session->GetPlayer();
auto queryResult = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
"(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
"FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
"(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ "
"FROM gameobject WHERE map='%u' AND (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) <= %f ORDER BY order_",
pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
pl->GetMapId(), pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), distance * distance);

Expand Down
2 changes: 1 addition & 1 deletion src/game/Chat/Level3.cpp
Expand Up @@ -5847,7 +5847,7 @@ bool ChatHandler::HandleBanInfoIPCommand(char* args)

bool ChatHandler::HandleBanListCharacterCommand(char* args)
{
LoginDatabase.Execute("DELETE FROM ip_banned WHERE expires_at<=UNIX_TIMESTAMP() AND expires_at<>banned_at");
LoginDatabase.Execute("DELETE FROM ip_banned WHERE expires_at<=" _UNIXTIME_ " AND expires_at<>banned_at");

char* cFilter = ExtractLiteralArg(&args);
if (!cFilter)
Expand Down
2 changes: 1 addition & 1 deletion src/game/GameEvents/GameEventMgr.cpp
Expand Up @@ -763,7 +763,7 @@ uint32 GameEventMgr::Initialize() // return the next e
}
while (queryResult->NextRow());

CharacterDatabase.Execute("TRUNCATE game_event_status");
CharacterDatabase.Execute(_TRUNCATE_ " game_event_status");
}

uint32 delay = Update(&activeAtShutdown);
Expand Down
4 changes: 2 additions & 2 deletions src/game/Maps/MapPersistentStateMgr.cpp
Expand Up @@ -1067,7 +1067,7 @@ void MapPersistentStateManager::InitWorldMaps()
void MapPersistentStateManager::LoadCreatureRespawnTimes()
{
// remove outdated data
CharacterDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");
CharacterDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= " _UNIXNOW_);

uint32 count = 0;

Expand Down Expand Up @@ -1136,7 +1136,7 @@ void MapPersistentStateManager::LoadCreatureRespawnTimes()
void MapPersistentStateManager::LoadGameobjectRespawnTimes()
{
// remove outdated data
CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");
CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= " _UNIXNOW_);

uint32 count = 0;

Expand Down
6 changes: 3 additions & 3 deletions src/game/Server/WorldSocket.cpp
Expand Up @@ -451,9 +451,9 @@ bool WorldSocket::HandleAuthSession(WorldPacket& recvPacket)

// Re-check account ban (same check as in realmd)
auto banresult =
LoginDatabase.PQuery("SELECT 1 FROM account_banned WHERE account_id = %u AND active = 1 AND (expires_at > UNIX_TIMESTAMP() OR expires_at = banned_at)"
LoginDatabase.PQuery("SELECT 1 FROM account_banned WHERE account_id = %u AND active = 1 AND (expires_at > " _UNIXTIME_ " OR expires_at = banned_at)"
"UNION "
"SELECT 1 FROM ip_banned WHERE (expires_at = banned_at OR expires_at > UNIX_TIMESTAMP()) AND ip = '%s'",
"SELECT 1 FROM ip_banned WHERE (expires_at = banned_at OR expires_at > " _UNIXTIME_ ") AND ip = '%s'",
id, GetRemoteAddress().c_str());

if (banresult) // if account banned
Expand Down Expand Up @@ -525,7 +525,7 @@ bool WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// No SQL injection, username escaped.
static SqlStatementID updAccount;

SqlStatement stmt = LoginDatabase.CreateStatement(updAccount, "INSERT INTO account_logons(accountId,ip,loginTime,loginSource) VALUES(?,?,NOW(),?)");
SqlStatement stmt = LoginDatabase.CreateStatement(updAccount, "INSERT INTO account_logons(accountId,ip,loginTime,loginSource) VALUES(?,?," _NOW_ ",?)");
stmt.PExecute(id, address.c_str(), std::to_string(LOGIN_TYPE_MANGOSD).c_str());

m_crypt.Init(&K);
Expand Down
20 changes: 11 additions & 9 deletions src/game/World/World.cpp
Expand Up @@ -952,7 +952,7 @@ void World::SetInitialWorldSettings()
LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%u'", server_type, realm_zone, realmID);

///- Remove the bones (they should not exist in DB though) and old corpses after a restart
CharacterDatabase.PExecute("DELETE FROM corpse WHERE corpse_type = '0' OR time < (UNIX_TIMESTAMP()-'%u')", 3 * DAY);
CharacterDatabase.PExecute("DELETE FROM corpse WHERE corpse_type = '0' OR time < (" _UNIXTIME_ "-'%u')", 3 * DAY);

// load SQL dbcs first, other DBCs need them
sObjectMgr.LoadSQLDBCs();
Expand Down Expand Up @@ -1474,7 +1474,8 @@ void World::SetInitialWorldSettings()
CheckLootTemplates_Reference(ids_set);

sLog.outString("Deleting expired bans...");
LoginDatabase.Execute("DELETE FROM ip_banned WHERE expires_at<=UNIX_TIMESTAMP() AND expires_at<>banned_at");

LoginDatabase.Execute("DELETE FROM ip_banned WHERE expires_at<=" _UNIXTIME_ " AND expires_at<>banned_at");
sLog.outString();

sLog.outString("Calculate next daily quest reset time...");
Expand Down Expand Up @@ -1994,17 +1995,17 @@ void World::WarnAccount(uint32 accountId, std::string from, std::string reason,
reason = std::string(type) + ": " + reason;
LoginDatabase.escape_string(reason);

LoginDatabase.PExecute("INSERT INTO account_banned (account_id, banned_at, expires_at, banned_by, reason, active) VALUES ('%u', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+1, '%s', '%s', '0')",
LoginDatabase.PExecute("INSERT INTO account_banned (account_id, banned_at, expires_at, banned_by, reason, active) VALUES ('%u', " _UNIXTIME_ ", " _UNIXTIME_ "+1, '%s', '%s', '0')",
accountId, from.c_str(), reason.c_str());
}

BanReturn World::BanAccount(WorldSession *session, uint32 duration_secs, const std::string& reason, const std::string& author)
{
if (duration_secs)
LoginDatabase.PExecute("INSERT INTO account_banned(account_id, banned_at, expires_at, banned_by, reason, active) VALUES ('%u', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+%u, '%s', '%s', '1')",
LoginDatabase.PExecute("INSERT INTO account_banned(account_id, banned_at, expires_at, banned_by, reason, active) VALUES ('%u', " _UNIXTIME_ ", " _UNIXTIME_ "+%u, '%s', '%s', '1')",
session->GetAccountId(), duration_secs, author.c_str(), reason.c_str());
else
LoginDatabase.PExecute("INSERT INTO account_banned(account_id, banned_at, expires_at, banned_by, reason, active) VALUES ('%u', UNIX_TIMESTAMP(), 0, '%s', '%s', '1')",
LoginDatabase.PExecute("INSERT INTO account_banned(account_id, banned_at, expires_at, banned_by, reason, active) VALUES ('%u', " _UNIXTIME_ ", 0, '%s', '%s', '1')",
session->GetAccountId(), author.c_str(), reason.c_str());

session->KickPlayer();
Expand All @@ -2027,7 +2028,7 @@ BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, uint32 duration_
case BAN_IP:
// No SQL injection as strings are escaped
resultAccounts = LoginDatabase.PQuery("SELECT accountId FROM account_logons WHERE ip = '%s' ORDER BY loginTime DESC LIMIT 1", nameOrIP.c_str());
LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+%u,'%s','%s')", nameOrIP.c_str(), duration_secs, safe_author.c_str(), reason.c_str());
LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s'," _UNIXTIME_ "," _UNIXTIME_ "+%u,'%s','%s')", nameOrIP.c_str(), duration_secs, safe_author.c_str(), reason.c_str());
break;
case BAN_ACCOUNT:
// No SQL injection as string is escaped
Expand Down Expand Up @@ -2058,7 +2059,7 @@ BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, uint32 duration_
if (mode != BAN_IP)
{
// No SQL injection as strings are escaped
LoginDatabase.PExecute("INSERT INTO account_banned(account_id, banned_at, expires_at, banned_by, reason, active) VALUES ('%u', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+%u, '%s', '%s', '1')",
LoginDatabase.PExecute("INSERT INTO account_banned(account_id, banned_at, expires_at, banned_by, reason, active) VALUES ('%u', " _UNIXTIME_ ", " _UNIXTIME_ "+%u, '%s', '%s', '1')",
account, duration_secs, safe_author.c_str(), reason.c_str());
}

Expand Down Expand Up @@ -2091,7 +2092,7 @@ bool World::RemoveBanAccount(BanMode mode, const std::string& source, const std:
return false;

// NO SQL injection as account is uint32
LoginDatabase.PExecute("UPDATE account_banned SET active = '0', unbanned_at = UNIX_TIMESTAMP(), unbanned_by = '%s' WHERE account_id = '%u'", source.data(), account);
LoginDatabase.PExecute("UPDATE account_banned SET active = '0', unbanned_at = " _UNIXTIME_ ", unbanned_by = '%s' WHERE account_id = '%u'", source.data(), account);
WarnAccount(account, source, message, "UNBAN");
}
return true;
Expand Down Expand Up @@ -2541,7 +2542,8 @@ void World::ResetWeeklyQuests()
void World::ResetMonthlyQuests()
{
DETAIL_LOG("Monthly quests reset for all characters.");
CharacterDatabase.Execute("TRUNCATE character_queststatus_monthly");

CharacterDatabase.Execute(_TRUNCATE_ " character_queststatus_monthly");

for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
if (itr->second->GetPlayer())
Expand Down
10 changes: 5 additions & 5 deletions src/realmd/AuthSocket.cpp
Expand Up @@ -382,7 +382,7 @@ bool AuthSocket::_HandleLogonChallenge()
///- Verify that this IP is not in the ip_banned table
// No SQL injection possible (paste the IP address as passed by the socket)
std::unique_ptr<QueryResult> ip_banned_result(LoginDatabase.PQuery("SELECT expires_at FROM ip_banned "
"WHERE (expires_at = banned_at OR expires_at > UNIX_TIMESTAMP()) AND ip = '%s'", m_address.c_str()));
"WHERE (expires_at = banned_at OR expires_at > " _UNIXTIME_ ") AND ip = '%s'", m_address.c_str()));

if (ip_banned_result)
{
Expand Down Expand Up @@ -431,7 +431,7 @@ bool AuthSocket::_HandleLogonChallenge()
{
///- If the account is banned, reject the logon attempt
auto banresult = LoginDatabase.PQuery("SELECT banned_at,expires_at FROM account_banned WHERE "
"account_id = %u AND active = 1 AND (expires_at > UNIX_TIMESTAMP() OR expires_at = banned_at)", fields[0].GetUInt32());
"account_id = %u AND active = 1 AND (expires_at > " _UNIXTIME_ " OR expires_at = banned_at)", fields[0].GetUInt32());
if (banresult)
{
if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64())
Expand Down Expand Up @@ -595,7 +595,7 @@ bool AuthSocket::_HandleLogonProof()
LoginDatabase.PExecute("UPDATE account SET sessionkey = '%s', locale = '%s', failed_logins = 0, os = '%s', platform = '%s' WHERE username = '%s'", K_hex, _safelocale.c_str(), m_os.c_str(), m_platform.c_str(), _safelogin.c_str());
std::unique_ptr<QueryResult> loginfail(LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", _safelogin.c_str()));
if (loginfail)
LoginDatabase.PExecute("INSERT INTO account_logons(accountId,ip,loginTime,loginSource) VALUES('%u','%s',NOW(),'%u')", loginfail->Fetch()[0].GetUInt32(), m_address.c_str(), LOGIN_TYPE_REALMD);
LoginDatabase.PExecute("INSERT INTO account_logons(accountId,ip,loginTime,loginSource) VALUES('%u','%s'," _NOW_ ",'%u')", loginfail->Fetch()[0].GetUInt32(), m_address.c_str(), LOGIN_TYPE_REALMD);
OPENSSL_free((void*)K_hex);

///- Finish SRP6 and send the final result to the client
Expand Down Expand Up @@ -643,7 +643,7 @@ bool AuthSocket::_HandleLogonProof()
{
uint32 acc_id = fields[0].GetUInt32();
LoginDatabase.PExecute("INSERT INTO account_banned(account_id, banned_at, expires_at, banned_by, reason, active)"
"VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)",
"VALUES ('%u'," _UNIXTIME_ "," _UNIXTIME_ "+'%u','MaNGOS realmd','Failed login autoban',1)",
acc_id, WrongPassBanTime);
BASIC_LOG("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
_login.c_str(), WrongPassBanTime, failed_logins);
Expand All @@ -652,7 +652,7 @@ bool AuthSocket::_HandleLogonProof()
{
std::string current_ip = m_address;
LoginDatabase.escape_string(current_ip);
LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')",
LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s'," _UNIXTIME_ "," _UNIXTIME_ "+'%u','MaNGOS realmd','Failed login autoban')",
current_ip.c_str(), WrongPassBanTime);
BASIC_LOG("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
Expand Down
4 changes: 2 additions & 2 deletions src/realmd/Main.cpp
Expand Up @@ -227,8 +227,8 @@ int main(int argc, char* argv[])
// cleanup query
// set expired bans to inactive
LoginDatabase.BeginTransaction();
LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE expires_at<=UNIX_TIMESTAMP() AND expires_at<>banned_at");
LoginDatabase.Execute("DELETE FROM ip_banned WHERE expires_at<=UNIX_TIMESTAMP() AND expires_at<>banned_at");
LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE expires_at<=" _UNIXTIME_ " AND expires_at<>banned_at");
LoginDatabase.Execute("DELETE FROM ip_banned WHERE expires_at<=" _UNIXTIME_ " AND expires_at<>banned_at");
LoginDatabase.CommitTransaction();

// FIXME - more intelligent selection of thread count is needed here. config option?
Expand Down
7 changes: 7 additions & 0 deletions src/shared/CMakeLists.txt
Expand Up @@ -46,6 +46,8 @@ set(SRC_GRP_DATABASE
Database/DatabaseMysql.h
Database/DatabasePostgre.cpp
Database/DatabasePostgre.h
Database/DatabaseSqlite.cpp
Database/DatabaseSqlite.h
Database/Field.cpp
Database/Field.h
Database/PGSQLDelayThread.h
Expand All @@ -54,6 +56,8 @@ set(SRC_GRP_DATABASE
Database/QueryResultMysql.h
Database/QueryResultPostgre.cpp
Database/QueryResultPostgre.h
Database/QueryResultSqlite.cpp
Database/QueryResultSqlite.h
Database/SqlDelayThread.cpp
Database/SqlDelayThread.h
Database/SqlOperations.cpp
Expand Down Expand Up @@ -244,6 +248,9 @@ endif()
if(POSTGRESQL AND POSTGRESQL_FOUND)
target_include_directories(${LIBRARY_NAME} PUBLIC ${PostgreSQL_INCLUDE_DIRS})
target_link_libraries(${LIBRARY_NAME} PUBLIC ${PostgreSQL_LIBRARIES})
elseif(SQLITE AND SQLite3_FOUND)
target_include_directories(${LIBRARY_NAME} PUBLIC ${SQLite3_INCLUDE_DIRS})
target_link_libraries(${LIBRARY_NAME} PUBLIC ${SQLite3_LIBRARIES})
else()
target_include_directories(${LIBRARY_NAME} PUBLIC ${MYSQL_INCLUDE_DIR})
target_link_libraries(${LIBRARY_NAME} PUBLIC ${MYSQL_LIBRARY})
Expand Down
1 change: 1 addition & 0 deletions src/shared/Database/Database.h
Expand Up @@ -24,6 +24,7 @@
#include "Database/SqlDelayThread.h"
#include "Policies/ThreadingModel.h"
#include "SqlPreparedStatement.h"
#include "QueryResult.h"

#include <boost/thread/tss.hpp>
#include <atomic>
Expand Down
21 changes: 21 additions & 0 deletions src/shared/Database/DatabaseEnv.h
Expand Up @@ -35,6 +35,23 @@ typedef DatabasePostgre DatabaseType;
#define _TABLE_SIM_ "\""
#define _CONCAT3_(A,B,C) "( " A " || " B " || " C " )"
#define _OFFSET_ "LIMIT 1 OFFSET %d"
#define _TRUNCATE_ "TRUNCATE TABLE"
#define _NOW_ "NOW()"
#define _UNIXTIME_ "UNIX_TIMESTAMP()"
#define _UNIXNOW_ "UNIX_TIMESTAMP(NOW())"
#elif DO_SQLITE
#include "Database/QueryResultSqlite.h"
#include "Database/Database.h"
#include "Database/DatabaseSqlite.h"
typedef DatabaseSqlite DatabaseType;
#define _LIKE_ "LIKE"
#define _TABLE_SIM_ '`'
#define _CONCAT3_(A,B,C) "( " A " || " B " || " C " )"
#define _OFFSET_ "LIMIT %d,1"
#define _TRUNCATE_ "DELETE FROM"
#define _NOW_ "datetime()"
#define _UNIXTIME_ "unixepoch()"
#define _UNIXNOW_ "unixepoch('now')"
#else
#include "Database/QueryResultMysql.h"
#include "Database/Database.h"
Expand All @@ -44,6 +61,10 @@ typedef DatabaseMysql DatabaseType;
#define _TABLE_SIM_ '`'
#define _CONCAT3_(A,B,C) "CONCAT( " A " , " B " , " C " )"
#define _OFFSET_ "LIMIT %d,1"
#define _TRUNCATE_ "TRUNCATE TABLE"
#define _NOW_ "NOW()"
#define _UNIXTIME_ "UNIX_TIMESTAMP()"
#define _UNIXNOW_ "UNIX_TIMESTAMP(NOW())"
#endif

extern DatabaseType WorldDatabase;
Expand Down

0 comments on commit ab9ce01

Please sign in to comment.