EQ2EMu/EQ2/source/common/database.h
2020-04-23 15:09:39 -04:00

181 lines
4.3 KiB
C++

/*
EQ2Emulator: Everquest II Server Emulator
Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
This file is part of EQ2Emulator.
EQ2Emulator is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
EQ2Emulator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EQ2EMU_DATABASE_H
#define EQ2EMU_DATABASE_H
#ifdef WIN32
#include <WinSock2.h>
#include <windows.h>
#endif
#include <mysql.h>
#include "dbcore.h"
#include "types.h"
#include "linked_list.h"
#include "EQStream.h"
#include "MiscFunctions.h"
#include "Mutex.h"
#include <string>
#include <vector>
#include <map>
using namespace std;
class Query;
class Database : public DBcore
{
public:
Database();
~Database();
bool Init(bool silentLoad=false);
bool LoadVariables();
void HandleMysqlError(int32 errnum);
map<string, uint16> GetOpcodes(int16 version);
map<int16, int16> GetVersions();
#ifdef WORLD
void AddAsyncQuery(Query* query);
void RunAsyncQueries(int32 queryid);
Database* FindFreeInstance();
void RemoveActiveQuery(Query* query);
void AddActiveQuery(Query* query);
bool IsActiveQuery(int32 id, Query* skip=0);
void PingAsyncDatabase();
#endif
protected:
private:
void InitVars();
#ifdef WORLD
void PurgeDBInstances();
void FreeDBInstance(Database* cur);
bool continueAsync;
map<int32, deque<Query*>> asyncQueries;
map<int32, Mutex*> asyncQueriesMutex;
map<Database*, bool> dbInstances;
vector<Query*> activeQuerySessions;
Mutex DBAsyncMutex;
Mutex DBInstanceMutex;
Mutex DBQueryMutex;
#endif
};
typedef struct {
int32 queryid;
}DBStruct;
class Query{
public:
Query() {
result = 0;
affected_rows = 0;
last_insert_id = 0;
errnum = 0;
row = 0;
retry = true;
escaped_name = 0;
escaped_pass = 0;
escaped_data1 = 0;
multiple_results = 0;
memset(errbuf, 0, sizeof(errbuf));
queryID = 0;
}
Query(Query* queryPtr, int32 in_id) {
result = 0;
affected_rows = 0;
last_insert_id = 0;
errnum = 0;
row = 0;
retry = true;
escaped_name = 0;
escaped_pass = 0;
escaped_data1 = 0;
multiple_results = 0;
memset(errbuf, 0, sizeof(errbuf));
query = string(queryPtr->GetQuery());
in_type = queryPtr->GetQueryType();
queryID = in_id;
}
~Query(){
if(result)
mysql_free_result(result);
result = 0;
safe_delete(affected_rows);
safe_delete(last_insert_id);
safe_delete_array(escaped_name);
safe_delete_array(escaped_pass);
safe_delete_array(escaped_data1);
if(multiple_results){
vector<MYSQL_RES*>::iterator itr;
for(itr = multiple_results->begin(); itr != multiple_results->end(); itr++){
mysql_free_result(*itr);
}
safe_delete(multiple_results);
}
}
int32 GetLastInsertedID() { return *last_insert_id; }
int32 GetAffectedRows() { return *affected_rows; }
MYSQL_RES* GetResult() { return result; }
MYSQL_RES* RunQuery2(string in_query, QUERY_TYPE type);
char* GetError() { return errbuf; }
int32 GetErrorNumber(){ return errnum; }
const char* GetQuery() { return query.c_str(); }
char* GetField(int8 field_num) {
if(!row && result)
*row = mysql_fetch_row(result);
if(row && result && field_num < mysql_num_fields(result))
return *row[field_num];
else
return NULL;
}
void NextRow(){
if(result)
*row = mysql_fetch_row(result);
}
void AddQueryAsync(int32 queryID, Database* db, QUERY_TYPE type, const char* format, ...);
void RunQueryAsync(Database* db);
MYSQL_RES* RunQuery2(QUERY_TYPE type, const char* format, ...);
QUERY_TYPE GetQueryType() {
return in_type;
}
int32 GetQueryID() { return queryID; }
char* escaped_name;
char* escaped_pass;
char* escaped_data1;
private:
string query;
char errbuf[MYSQL_ERRMSG_SIZE];
MYSQL_RES *result;
vector<MYSQL_RES*>* multiple_results;
int32* affected_rows;
int32* last_insert_id;
int32 errnum;
QUERY_TYPE in_type;
bool retry;
MYSQL_ROW* row;
MYSQL mysql;
int32 queryID;
};
#endif