summaryrefslogtreecommitdiff
path: root/modules/extra/m_mysql.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/extra/m_mysql.cpp')
-rw-r--r--modules/extra/m_mysql.cpp81
1 files changed, 49 insertions, 32 deletions
diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp
index e83e78c7c..0696955cd 100644
--- a/modules/extra/m_mysql.cpp
+++ b/modules/extra/m_mysql.cpp
@@ -49,7 +49,7 @@ class MySQLResult : public SQLResult
MYSQL_RES *res;
public:
- MySQLResult(const SQLQuery &q, const Anope::string &fq, MYSQL_RES *r) : SQLResult(q, fq), res(r)
+ MySQLResult(unsigned int i, const SQLQuery &q, const Anope::string &fq, MYSQL_RES *r) : SQLResult(i, q, fq), res(r)
{
unsigned num_fields = res ? mysql_num_fields(res) : 0;
@@ -80,7 +80,7 @@ class MySQLResult : public SQLResult
}
}
- MySQLResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err) : SQLResult(q, fq, err), res(NULL)
+ MySQLResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err) : SQLResult(0, q, fq, err), res(NULL)
{
}
@@ -95,6 +95,8 @@ class MySQLResult : public SQLResult
*/
class MySQLService : public SQLProvider
{
+ std::map<Anope::string, std::set<Anope::string> > active_schema;
+
Anope::string database;
Anope::string server;
Anope::string user;
@@ -123,7 +125,7 @@ class MySQLService : public SQLProvider
SQLResult RunQuery(const SQLQuery &query) anope_override;
- SQLQuery CreateTable(const Anope::string &table, const Serializable::serialized_data &data) anope_override;
+ std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) anope_override;
SQLQuery GetTables() anope_override;
@@ -305,7 +307,7 @@ MySQLService::~MySQLService()
if (r.service == this)
{
if (r.sqlinterface)
- r.sqlinterface->OnError(SQLResult(r.query, "SQL Interface is going away"));
+ r.sqlinterface->OnError(SQLResult(0, r.query, "SQL Interface is going away"));
me->QueryRequests.erase(me->QueryRequests.begin() + i - 1);
}
}
@@ -329,10 +331,11 @@ SQLResult MySQLService::RunQuery(const SQLQuery &query)
if (this->CheckConnection() && !mysql_real_query(this->sql, real_query.c_str(), real_query.length()))
{
- MYSQL_RES *res = mysql_use_result(this->sql);
+ MYSQL_RES *res = mysql_store_result(this->sql);
+ unsigned int id = mysql_insert_id(this->sql);
this->Lock.Unlock();
- return MySQLResult(query, real_query, res);
+ return MySQLResult(id, query, real_query, res);
}
else
{
@@ -342,38 +345,50 @@ SQLResult MySQLService::RunQuery(const SQLQuery &query)
}
}
-SQLQuery MySQLService::CreateTable(const Anope::string &table, const Serializable::serialized_data &data)
+std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, const Serialize::Data &data)
{
- Anope::string query_text = "CREATE TABLE `" + table + "` (", key_buf;
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- {
- query_text += "`" + it->first + "` ";
- if (it->second.getType() == Serialize::DT_INT)
- query_text += "int(11)";
- else if (it->second.getMax() > 0)
- query_text += "varchar(" + stringify(it->second.getMax()) + ")";
- else
- query_text += "text";
- query_text += ",";
+ std::vector<SQLQuery> queries;
+ std::set<Anope::string> &known_cols = this->active_schema[table];
- if (it->second.getKey())
+ if (known_cols.empty())
+ {
+ Anope::string query_text = "CREATE TABLE IF NOT EXISTS `" + table + "` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
+ " `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP";
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
{
- if (key_buf.empty())
- key_buf = "UNIQUE KEY `ukey` (";
- key_buf += "`" + it->first + "`,";
+ known_cols.insert(it->first);
+
+ query_text += ", `" + it->first + "` ";
+ if (it->second.getType() == Serialize::DT_INT)
+ query_text += "int(11)";
+ else if (it->second.getMax() > 0)
+ query_text += "varchar(" + stringify(it->second.getMax()) + ")";
+ else
+ query_text += "text";
}
- }
- if (!key_buf.empty())
- {
- key_buf.erase(key_buf.end() - 1);
- key_buf += ")";
- query_text += " " + key_buf;
+ query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`))";
+ queries.push_back(query_text);
}
else
- query_text.erase(query_text.end() - 1);
- query_text += ")";
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ {
+ if (known_cols.count(it->first) > 0)
+ continue;
+
+ known_cols.insert(it->first);
+
+ Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` ";
+ if (it->second.getType() == Serialize::DT_INT)
+ query_text += "int(11)";
+ else if (it->second.getMax() > 0)
+ query_text += "varchar(" + stringify(it->second.getMax()) + ")";
+ else
+ query_text += "text";
+
+ queries.push_back(query_text);
+ }
- return SQLQuery(query_text);
+ return queries;
}
SQLQuery MySQLService::GetTables()
@@ -391,7 +406,9 @@ void MySQLService::Connect()
bool connect = mysql_real_connect(this->sql, this->server.c_str(), this->user.c_str(), this->password.c_str(), this->database.c_str(), this->port, NULL, 0);
if (!connect)
- throw SQLException("Unable to connect to SQL service " + this->name + ": " + mysql_error(this->sql));
+ throw SQLException("Unable to connect to MySQL service " + this->name + ": " + mysql_error(this->sql));
+
+ Log(LOG_DEBUG) << "Successfully connected to MySQL service " << this->name << " at " << this->server << ":" << this->port;
}