* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
+ * InspIRCd is copyright (C) 2002-2004 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
* ---------------------------------------------------
*/
+using namespace std;
#include <stdio.h>
#include <string>
-#include <mysql/mysql.h>
+#include <mysql.h>
#include "users.h"
#include "channels.h"
#include "modules.h"
+#include "helperfuncs.h"
#include "m_sql.h"
-/* $ModDesc: m_filter with regexps */
-/* $CompileFlags: -I/usr/local/include -I/usr/include -L/usr/local/lib/mysql -L/usr/lib/mysql -lmysqlclient */
+/* $ModDesc: SQL Service Provider module for all other m_sql* modules */
+/* $CompileFlags: -I/usr/local/include/mysql -I/usr/include/mysql -I/usr/local/include -I/usr/include */
+/* $LinkerFlags: -L/usr/local/lib/mysql -Wl,--rpath -Wl,/usr/local/lib/mysql -L/usr/lib/mysql -Wl,--rpath -Wl,/usr/lib/mysql -lmysqlclient */
/** SQLConnection represents one mysql session.
* Each session has its own persistent connection to the database.
*/
+
+#if !defined(MYSQL_VERSION_ID) || MYSQL_VERSION_ID<32224
+#define mysql_field_count mysql_num_fields
+#endif
+
class SQLConnection
{
protected:
this->pass = thispass;
this->db = thisdb;
this->id = myid;
+ unsigned int timeout = 1;
mysql_init(&connection);
+ mysql_options(&connection,MYSQL_OPT_CONNECT_TIMEOUT,(char*)&timeout);
}
// This method connects to the database using the credentials supplied to the constructor, and returns
// multiple rows.
bool QueryResult(std::string query)
{
- char escaped_query[query.length()+1];
- mysql_real_escape_string(&connection, escaped_query, query.c_str(), query.length());
- int r = mysql_query(&connection, escaped_query);
+ int r = mysql_query(&connection, query.c_str());
if (!r)
{
res = mysql_use_result(&connection);
// the number of effected rows is returned in the return value.
unsigned long QueryCount(std::string query)
{
- char escaped_query[query.length()+1];
- mysql_real_escape_string(&connection, escaped_query, query.c_str(), query.length());
- int r = mysql_query(&connection, escaped_query);
+ int r = mysql_query(&connection, query.c_str());
if (!r)
{
res = mysql_store_result(&connection);
if (row)
{
unsigned int field_count = 0;
+ MYSQL_FIELD *fields = mysql_fetch_fields(res);
if(mysql_field_count(&connection) == 0)
return thisrow;
- MYSQL_FIELD *fields = mysql_fetch_fields(res);
- while (field_count < mysql_field_count(&connection))
+ if (fields && mysql_field_count(&connection))
{
- thisrow[std::string(fields[field_count].name)] = std::string(row[field_count]);
- field_count++;
+ while (field_count < mysql_field_count(&connection))
+ {
+ std::string a = (fields[field_count].name ? fields[field_count].name : "");
+ std::string b = (row[field_count] ? row[field_count] : "");
+ thisrow[a] = b;
+ field_count++;
+ }
+ return thisrow;
}
- return thisrow;
}
}
return thisrow;
return Enabled;
}
- ~SQLConnection()
- {
- mysql_close(&connection);
- }
};
typedef std::vector<SQLConnection> ConnectionList;
}
}
- void LoadDatabases(ConfigReader* Conf)
+ void LoadDatabases(ConfigReader* ThisConf)
{
Srv->Log(DEFAULT,"SQL: Loading database settings");
Connections.clear();
- for (int j =0; j < Conf->Enumerate("database"); j++)
+ Srv->Log(DEBUG,"Cleared connections");
+ for (int j =0; j < ThisConf->Enumerate("database"); j++)
{
- std::string db = Conf->ReadValue("database","name",j);
- std::string user = Conf->ReadValue("database","username",j);
- std::string pass = Conf->ReadValue("database","password",j);
- std::string host = Conf->ReadValue("database","hostname",j);
- std::string id = Conf->ReadValue("database","id",j);
+ std::string db = ThisConf->ReadValue("database","name",j);
+ std::string user = ThisConf->ReadValue("database","username",j);
+ std::string pass = ThisConf->ReadValue("database","password",j);
+ std::string host = ThisConf->ReadValue("database","hostname",j);
+ std::string id = ThisConf->ReadValue("database","id",j);
+ Srv->Log(DEBUG,"Read database settings");
if ((db != "") && (host != "") && (user != "") && (id != "") && (pass != ""))
{
SQLConnection ThisSQL(host,user,pass,db,atoi(id.c_str()));
Srv->Log(DEFAULT,"Loaded database: "+ThisSQL.GetHost());
Connections.push_back(ThisSQL);
+ Srv->Log(DEBUG,"Pushed back connection");
}
}
ConnectDatabases();
{
for (ConnectionList::iterator i = Connections.begin(); i != Connections.end(); i++)
{
- if ((i->GetID() == r->GetConnID()) && (i->Enabled()))
+ if ((i->GetID() == r->GetConnID()) && (i->IsEnabled()))
{
bool xr = i->QueryResult(r->GetQuery());
if (!xr)
{
res->SetType(SQL_ERROR);
- res->SetError(r->GetError());
+ res->SetError(i->GetError());
return;
}
+ res->SetType(SQL_OK);
+ return;
}
}
}
{
for (ConnectionList::iterator i = Connections.begin(); i != Connections.end(); i++)
{
- if ((i->GetID() == r->GetConnID()) && (i->Enabled()))
+ if ((i->GetID() == r->GetConnID()) && (i->IsEnabled()))
{
res->SetType(SQL_COUNT);
res->SetCount(i->QueryCount(r->GetQuery()));
}
}
+ void DoneType(SQLRequest *r, SQLResult* res)
+ {
+ for (ConnectionList::iterator i = Connections.begin(); i != Connections.end(); i++)
+ {
+ if ((i->GetID() == r->GetConnID()) && (i->IsEnabled()))
+ {
+ res->SetType(SQL_DONE);
+ if (!i->QueryDone())
+ res->SetType(SQL_ERROR);
+ }
+ }
+ }
+
void RowType(SQLRequest *r, SQLResult* res)
{
for (ConnectionList::iterator i = Connections.begin(); i != Connections.end(); i++)
{
- if ((i->GetID() == r->GetConnID()) && (i->Enabled()))
+ if ((i->GetID() == r->GetConnID()) && (i->IsEnabled()))
{
+ log(DEBUG,"*** FOUND MATCHING ROW");
std::map<std::string,std::string> row = i->GetRow();
res->SetRow(row);
res->SetType(SQL_ROW);
if (!row.size())
+ {
+ log(DEBUG,"ROW SIZE IS 0");
res->SetType(SQL_END);
+ }
return;
}
}
}
+ void Implements(char* List)
+ {
+ List[I_OnRehash] = List[I_OnRequest] = 1;
+ }
+
char* OnRequest(Request* request)
{
- SQLResult Result = new SQLResult();
- SQLRequest *r = (SQLRequest*)request;
- switch (r->GetRequest())
+ if (request)
{
- case SQL_RESULT:
- ResultType(r,Result);
- break;
- case SQL_COUNT:
- CountType(r,Result);
- break;
- case SQL_ROW:
- RowType(r,Result);
- break;
+ SQLResult* Result = new SQLResult();
+ SQLRequest *r = (SQLRequest*)request->GetData();
+ switch (r->GetQueryType())
+ {
+ case SQL_RESULT:
+ ResultType(r,Result);
+ break;
+ case SQL_COUNT:
+ CountType(r,Result);
+ break;
+ case SQL_ROW:
+ RowType(r,Result);
+ break;
+ case SQL_DONE:
+ DoneType(r,Result);
+ break;
+ }
+ return (char*)Result;
}
- return Result;
+ return NULL;
}
- ModuleSQL()
+ ModuleSQL(Server* Me)
+ : Module::Module(Me)
{
- Srv = new Server();
+ Srv = Me;
Conf = new ConfigReader();
LoadDatabases(Conf);
}
{
Connections.clear();
delete Conf;
- delete Srv;
}
- virtual void OnRehash()
+ virtual void OnRehash(std::string parameter)
{
delete Conf;
Conf = new ConfigReader();
{
}
- virtual Module * CreateModule()
+ virtual Module * CreateModule(Server* Me)
{
- return new ModuleSQL;
+ return new ModuleSQL(Me);
}
};