00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef INSPIRCD_SQLAPI_2
00015 #define INSPIRCD_SQLAPI_2
00016
00017 #include <string>
00018 #include <deque>
00019 #include <map>
00020 #include "modules.h"
00021
00024 #define SQLREQID "SQLv2 Request"
00025 #define SQLRESID "SQLv2 Result"
00026 #define SQLSUCCESS "You shouldn't be reading this (success)"
00027
00030 enum SQLerrorNum { SQL_NO_ERROR, SQL_BAD_DBID, SQL_BAD_CONN, SQL_QSEND_FAIL, SQL_QREPLY_FAIL };
00031
00034 typedef std::deque<std::string> ParamL;
00035
00038 class SQLexception : public ModuleException
00039 {
00040 public:
00041 SQLexception(const std::string &reason) : ModuleException(reason)
00042 {
00043 }
00044
00045 SQLexception() : ModuleException("SQLv2: Undefined exception")
00046 {
00047 }
00048 };
00049
00052 class SQLbadColName : public SQLexception
00053 {
00054 public:
00055 SQLbadColName() : SQLexception("SQLv2: Bad column name")
00056 {
00057 }
00058 };
00059
00064 class SQLerror : public classbase
00065 {
00068 SQLerrorNum id;
00071 std::string str;
00072 public:
00077 SQLerror(SQLerrorNum i = SQL_NO_ERROR, const std::string &s = "")
00078 : id(i), str(s)
00079 {
00080 }
00081
00084 SQLerrorNum Id()
00085 {
00086 return id;
00087 }
00088
00093 SQLerrorNum Id(SQLerrorNum i)
00094 {
00095 id = i;
00096 return id;
00097 }
00098
00102 void Str(const std::string &s)
00103 {
00104 str = s;
00105 }
00106
00109 const char* Str()
00110 {
00111 if(str.length())
00112 return str.c_str();
00113
00114 switch(id)
00115 {
00116 case SQL_NO_ERROR:
00117 return "No error";
00118 case SQL_BAD_DBID:
00119 return "Invalid database ID";
00120 case SQL_BAD_CONN:
00121 return "Invalid connection";
00122 case SQL_QSEND_FAIL:
00123 return "Sending query failed";
00124 case SQL_QREPLY_FAIL:
00125 return "Getting query result failed";
00126 default:
00127 return "Unknown error";
00128 }
00129 }
00130 };
00131
00152 class SQLquery : public classbase
00153 {
00154 public:
00157 std::string q;
00162 ParamL p;
00163
00166 SQLquery(const std::string &query)
00167 : q(query)
00168 {
00169 }
00170
00175 SQLquery(const std::string &query, const ParamL ¶ms)
00176 : q(query), p(params)
00177 {
00178 }
00179
00182 template<typename T> SQLquery& operator,(const T &foo)
00183 {
00184 p.push_back(ConvToStr(foo));
00185 return *this;
00186 }
00187
00191 template<typename T> SQLquery& operator%(const T &foo)
00192 {
00193 p.push_back(ConvToStr(foo));
00194 return *this;
00195 }
00196 };
00197
00203 class SQLrequest : public Request
00204 {
00205 public:
00209 SQLquery query;
00212 std::string dbid;
00216 bool pri;
00222 unsigned long id;
00225 SQLerror error;
00226
00238 SQLrequest(Module* s, Module* d, const std::string &databaseid, const SQLquery &q)
00239 : Request(s, d, SQLREQID), query(q), dbid(databaseid), pri(false), id(0)
00240 {
00241 }
00242
00245 void Priority(bool p = true)
00246 {
00247 pri = p;
00248 }
00249
00252 void SetSource(Module* mod)
00253 {
00254 source = mod;
00255 }
00256 };
00257
00262 class SQLfield
00263 {
00264 public:
00268 std::string d;
00269
00273 bool null;
00274
00277 SQLfield(const std::string &data = "", bool n = false)
00278 : d(data), null(n)
00279 {
00280
00281 }
00282 };
00283
00287 typedef std::vector<SQLfield> SQLfieldList;
00291 typedef std::map<std::string, SQLfield> SQLfieldMap;
00292
00301 class SQLresult : public Request
00302 {
00303 public:
00306 std::string query;
00309 std::string dbid;
00315 SQLerror error;
00320 unsigned long id;
00321
00324 SQLresult(Module* s, Module* d, unsigned long i)
00325 : Request(s, d, SQLRESID), id(i)
00326 {
00327 }
00328
00339 virtual int Rows() = 0;
00340
00348 virtual int Cols() = 0;
00349
00355 virtual std::string ColName(int column) = 0;
00356
00364 virtual int ColNum(const std::string &column) = 0;
00365
00371 virtual SQLfield GetValue(int row, int column) = 0;
00372
00385 virtual SQLfieldList& GetRow() = 0;
00386
00392 virtual SQLfieldMap& GetRowMap() = 0;
00393
00401 virtual SQLfieldList* GetRowPtr() = 0;
00402
00408 virtual SQLfieldMap* GetRowMapPtr() = 0;
00409
00415 virtual void Free(SQLfieldMap* fm) = 0;
00416
00422 virtual void Free(SQLfieldList* fl) = 0;
00423 };
00424
00425
00430 class SQLhost
00431 {
00432 public:
00433 std::string id;
00434 std::string host;
00435 std::string ip;
00436 unsigned int port;
00437 std::string name;
00438 std::string user;
00439 std::string pass;
00440 bool ssl;
00441
00442 SQLhost()
00443 : id(""), host(""), ip(""), port(0), name(""), user(""), pass(""), ssl(0)
00444 {
00445 }
00446
00447 SQLhost(const std::string& i, const std::string& h, unsigned int p, const std::string& n, const std::string& u, const std::string& pa, bool s)
00448 : id(i), host(h), ip(""), port(p), name(n), user(u), pass(pa), ssl(s)
00449 {
00450 }
00451
00455 std::string GetDSN();
00456 };
00457
00460 bool operator== (const SQLhost& l, const SQLhost& r)
00461 {
00462 return (l.id == r.id && l.host == r.host && l.port == r.port && l.name == r.name && l.user == r.user && l.pass == r.pass && l.ssl == r.ssl);
00463 }
00466 bool operator!= (const SQLhost& l, const SQLhost& r)
00467 {
00468 return (l.id != r.id || l.host != r.host || l.port != r.port || l.name != r.name || l.user != r.user || l.pass != r.pass || l.ssl != r.ssl);
00469 }
00470
00471
00497 class QueryQueue : public classbase
00498 {
00499 private:
00500 typedef std::deque<SQLrequest> ReqDeque;
00501
00502 ReqDeque priority;
00503 ReqDeque normal;
00504 enum { PRI, NOR, NON } which;
00505
00506 public:
00507 QueryQueue()
00508 : which(NON)
00509 {
00510 }
00511
00512 void push(const SQLrequest &q)
00513 {
00514 if(q.pri)
00515 priority.push_back(q);
00516 else
00517 normal.push_back(q);
00518 }
00519
00520 void pop()
00521 {
00522 if((which == PRI) && priority.size())
00523 {
00524 priority.pop_front();
00525 }
00526 else if((which == NOR) && normal.size())
00527 {
00528 normal.pop_front();
00529 }
00530
00531
00532 which = NON;
00533
00534
00535 }
00536
00537 SQLrequest& front()
00538 {
00539 switch(which)
00540 {
00541 case PRI:
00542 return priority.front();
00543 case NOR:
00544 return normal.front();
00545 default:
00546 if(priority.size())
00547 {
00548 which = PRI;
00549 return priority.front();
00550 }
00551
00552 if(normal.size())
00553 {
00554 which = NOR;
00555 return normal.front();
00556 }
00557
00558
00559
00560
00561
00562
00563 return priority.front();
00564 }
00565 }
00566
00567 std::pair<int, int> size()
00568 {
00569 return std::make_pair(priority.size(), normal.size());
00570 }
00571
00572 int totalsize()
00573 {
00574 return priority.size() + normal.size();
00575 }
00576
00577 void PurgeModule(Module* mod)
00578 {
00579 DoPurgeModule(mod, priority);
00580 DoPurgeModule(mod, normal);
00581 }
00582
00583 private:
00584 void DoPurgeModule(Module* mod, ReqDeque& q)
00585 {
00586 for(ReqDeque::iterator iter = q.begin(); iter != q.end(); iter++)
00587 {
00588 if(iter->GetSource() == mod)
00589 {
00590 if(iter->id == front().id)
00591 {
00592
00593 iter->SetSource(NULL);
00594 }
00595 else
00596 {
00597
00598 iter = q.erase(iter);
00599 }
00600 }
00601 }
00602 }
00603 };
00604
00605
00606 #endif