diff options
author | Adam <Adam@anope.org> | 2012-04-29 19:24:37 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2012-04-29 19:24:37 -0400 |
commit | 42e652cae79c0387e690f18e00712963c2dfec22 (patch) | |
tree | 6dc111a9df238a1f905622532c6a65890a8f0c4f /modules/extra | |
parent | 62818abbf4a39b7641ad2b84d1888ed03b653819 (diff) |
Pull table schemas from SQL on startup so we can alter the schemas if we need to, fixed sqlite to work again
Diffstat (limited to 'modules/extra')
-rw-r--r-- | modules/extra/m_mysql.cpp | 38 | ||||
-rw-r--r-- | modules/extra/m_sqlite.cpp | 48 | ||||
-rw-r--r-- | modules/extra/sql.h | 2 |
3 files changed, 82 insertions, 6 deletions
diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp index 8a7c21e64..2edf21745 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/m_mysql.cpp @@ -126,6 +126,8 @@ class MySQLService : public SQLProvider std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) anope_override; + SQLQuery BuildInsert(const Anope::string &table, unsigned int id, const Serialize::Data &data); + SQLQuery GetTables(const Anope::string &prefix) anope_override; void Connect(); @@ -351,7 +353,21 @@ std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, cons if (known_cols.empty()) { - Anope::string query_text = "CREATE TABLE IF NOT EXISTS `" + table + "` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT," + Log(LOG_DEBUG) << "m_mysql: Fetching columns for " << table; + + SQLResult columns = this->RunQuery("SHOW COLUMNS FROM `" + table + "`"); + for (int i = 0; i < columns.Rows(); ++i) + { + const Anope::string &column = columns.Get(i, "Field"); + + Log(LOG_DEBUG) << "m_mysql: Column #" << i << " for " << table << ": " << column; + known_cols.insert(column); + } + } + + if (known_cols.empty()) + { + Anope::string query_text = "CREATE TABLE `" + 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) { @@ -390,6 +406,26 @@ std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, cons return queries; } +SQLQuery MySQLService::BuildInsert(const Anope::string &table, unsigned int id, const Serialize::Data &data) +{ + Anope::string query_text = "INSERT INTO `" + table + "` (`id`"; + for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + query_text += ",`" + it->first + "`"; + query_text += ") VALUES (" + stringify(id); + for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + query_text += ",@" + it->first + "@"; + query_text += ") ON DUPLICATE KEY UPDATE "; + for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + query_text += "`" + it->first + "`=VALUES(`" + it->first + "`),"; + query_text.erase(query_text.end() - 1); + + SQLQuery query(query_text); + for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + query.setValue(it->first, it->second.astr()); + + return query; +} + SQLQuery MySQLService::GetTables(const Anope::string &prefix) { return SQLQuery("SHOW TABLES LIKE '" + prefix + "%';"); diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp index 5102c003b..fff3e67d1 100644 --- a/modules/extra/m_sqlite.cpp +++ b/modules/extra/m_sqlite.cpp @@ -48,6 +48,8 @@ class SQLiteService : public SQLProvider std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) anope_override; + SQLQuery BuildInsert(const Anope::string &table, unsigned int id, const Serialize::Data &data); + SQLQuery GetTables(const Anope::string &prefix); Anope::string BuildQuery(const SQLQuery &q); @@ -187,9 +189,23 @@ std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, con std::vector<SQLQuery> queries; std::set<Anope::string> &known_cols = this->active_schema[table]; - if (active_schema.empty()) + if (known_cols.empty()) { - Anope::string query_text = "CREATE TABLE IF NOT EXISTS `" + table + "` (id INTEGER PRIMARY KEY, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, "; + Log(LOG_DEBUG) << "m_sqlite: Fetching columns for " << table; + + SQLResult columns = this->RunQuery("PRAGMA table_info(" + table + ")"); + for (int i = 0; i < columns.Rows(); ++i) + { + const Anope::string &column = columns.Get(i, "name"); + + Log(LOG_DEBUG) << "m_sqlite: Column #" << i << " for " << table << ": " << column; + known_cols.insert(column); + } + } + + if (known_cols.empty()) + { + Anope::string query_text = "CREATE TABLE `" + table + "` (`id` INTEGER PRIMARY KEY, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"; for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) { @@ -202,15 +218,14 @@ std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, con query_text += "text"; } - query_text.erase(query_text.end() - 1); query_text += ")"; queries.push_back(query_text); - query_text = "CREATE UNIQUE INDEX IF NOT EXISTS `id_idx` ON `" + table + "` (`id`)"; + query_text = "CREATE UNIQUE INDEX `" + table + "_id_idx` ON `" + table + "` (`id`)"; queries.push_back(query_text); - query_text = "CREATE INDEX IF NOT EXISTS `timestamp_idx` ON `" + table + "` (`timestamp`)"; + query_text = "CREATE INDEX `" + table + "_timestamp_idx` ON `" + table + "` (`timestamp`)"; queries.push_back(query_text); query_text = "CREATE TRIGGER `" + table + "_trigger` AFTER UPDATE ON `" + table + "` FOR EACH ROW BEGIN UPDATE `" + table + "` SET `timestamp` = CURRENT_TIMESTAMP WHERE `id` = `old.id`; end;"; @@ -236,6 +251,29 @@ std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, con return queries; } +SQLQuery SQLiteService::BuildInsert(const Anope::string &table, unsigned int id, const Serialize::Data &data) +{ + Anope::string query_text = "REPLACE INTO `" + table + "` ("; + if (id > 0) + query_text += "`id`,"; + for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + query_text += "`" + it->first + "`,"; + query_text.erase(query_text.length() - 1); + query_text += ") VALUES ("; + if (id > 0) + query_text += stringify(id) + ","; + for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + query_text += "@" + it->first + "@,"; + query_text.erase(query_text.length() - 1); + query_text += ")"; + + SQLQuery query(query_text); + for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + query.setValue(it->first, it->second.astr()); + + return query; +} + SQLQuery SQLiteService::GetTables(const Anope::string &prefix) { return SQLQuery("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '" + prefix + "%';"); diff --git a/modules/extra/sql.h b/modules/extra/sql.h index 2e2e1840c..03c3c7694 100644 --- a/modules/extra/sql.h +++ b/modules/extra/sql.h @@ -129,6 +129,8 @@ class SQLProvider : public Service virtual std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) = 0; + virtual SQLQuery BuildInsert(const Anope::string &table, unsigned int id, const Serialize::Data &data) = 0; + virtual SQLQuery GetTables(const Anope::string &prefix) = 0; }; |