anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
tables.cpp (12795B)
1 /* 2 * 3 * (C) 2013-2022 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 */ 8 9 #include "irc2sql.h" 10 11 void IRC2SQL::CheckTables() 12 { 13 Anope::string geoquery(""); 14 15 if (firstrun) 16 { 17 /* 18 * reset some tables to make sure they are really empty 19 */ 20 this->sql->RunQuery("TRUNCATE TABLE " + prefix + "user"); 21 this->sql->RunQuery("TRUNCATE TABLE " + prefix + "chan"); 22 this->sql->RunQuery("TRUNCATE TABLE " + prefix + "ison"); 23 this->sql->RunQuery("UPDATE `" + prefix + "server` SET currentusers=0, online='N'"); 24 } 25 26 this->GetTables(); 27 28 if (GeoIPDB.equals_ci("country")) 29 { 30 if (!this->HasTable(prefix + "geoip_country")) 31 { 32 query = "CREATE TABLE `" + prefix + "geoip_country` (" 33 "`start` INT UNSIGNED NOT NULL," 34 "`end` INT UNSIGNED NOT NULL," 35 "`countrycode` varchar(2)," 36 "`countryname` varchar(50)," 37 "PRIMARY KEY `end` (`end`)," 38 "KEY `start` (`start`)" 39 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 40 this->RunQuery(query); 41 } 42 } 43 else if (GeoIPDB.equals_ci("city")) 44 { 45 if (!this->HasTable(prefix + "geoip_city_blocks")) 46 { 47 query = "CREATE TABLE `" + prefix + "geoip_city_blocks` (" 48 "`start` INT UNSIGNED NOT NULL," 49 "`end` INT UNSIGNED NOT NULL," 50 "`locId` INT UNSIGNED NOT NULL," 51 "PRIMARY KEY `end` (`end`)," 52 "KEY `start` (`start`)" 53 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 54 this->RunQuery(query); 55 } 56 if (!this->HasTable(prefix + "geoip_city_location")) 57 { 58 query = "CREATE TABLE `" + prefix + "geoip_city_location` (" 59 "`locId` INT UNSIGNED NOT NULL," 60 "`country` CHAR(2) NOT NULL," 61 "`region` CHAR(2) NOT NULL," 62 "`city` VARCHAR(50)," 63 "`latitude` FLOAT," 64 "`longitude` FLOAT," 65 "`areaCode` INT," 66 "PRIMARY KEY (`locId`)" 67 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 68 this->RunQuery(query); 69 } 70 if (!this->HasTable(prefix + "geoip_city_region")) 71 { query = "CREATE TABLE `" + prefix + "geoip_city_region` (" 72 "`country` CHAR(2) NOT NULL," 73 "`region` CHAR(2) NOT NULL," 74 "`regionname` VARCHAR(100) NOT NULL," 75 "PRIMARY KEY (`country`,`region`)" 76 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 77 this->RunQuery(query); 78 } 79 } 80 if (!this->HasTable(prefix + "server")) 81 { 82 query = "CREATE TABLE `" + prefix + "server` (" 83 "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT," 84 "`name` varchar(64) NOT NULL," 85 "`hops` tinyint(3) NOT NULL," 86 "`comment` varchar(255) NOT NULL," 87 "`link_time` datetime DEFAULT NULL," 88 "`split_time` datetime DEFAULT NULL," 89 "`version` varchar(127) DEFAULT NULL," 90 "`currentusers` int(15) DEFAULT 0," 91 "`online` enum('Y','N') NOT NULL DEFAULT 'Y'," 92 "`ulined` enum('Y','N') NOT NULL DEFAULT 'N'," 93 "PRIMARY KEY (`id`)," 94 "UNIQUE KEY `name` (`name`)" 95 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 96 this->RunQuery(query); 97 } 98 if (!this->HasTable(prefix + "chan")) 99 { 100 query = "CREATE TABLE `" + prefix + "chan` (" 101 "`chanid` int(11) UNSIGNED NOT NULL AUTO_INCREMENT," 102 "`channel` varchar(255) NOT NULL," 103 "`topic` varchar(512) DEFAULT NULL," 104 "`topicauthor` varchar(255) DEFAULT NULL," 105 "`topictime` datetime DEFAULT NULL," 106 "`modes` varchar(512) DEFAULT NULL," 107 "PRIMARY KEY (`chanid`)," 108 "UNIQUE KEY `channel`(`channel`)" 109 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 110 this->RunQuery(query); 111 } 112 if (!this->HasTable(prefix + "user")) 113 { 114 query = "CREATE TABLE `" + prefix + "user` (" 115 "`nickid` int(11) UNSIGNED NOT NULL AUTO_INCREMENT," 116 "`nick` varchar(255) NOT NULL DEFAULT ''," 117 "`host` varchar(255) NOT NULL DEFAULT ''," 118 "`vhost` varchar(255) NOT NULL DEFAULT ''," 119 "`chost` varchar(255) NOT NULL DEFAULT ''," 120 "`realname` varchar(255) NOT NULL DEFAULT ''," 121 "`ip` varchar(255) NOT NULL DEFAULT ''," 122 "`ident` varchar(32) NOT NULL DEFAULT ''," 123 "`vident` varchar(32) NOT NULL DEFAULT ''," 124 "`modes` varchar(255) NOT NULL DEFAULT ''," 125 "`account` varchar(255) NOT NULL DEFAULT ''," 126 "`secure` enum('Y','N') NOT NULL DEFAULT 'N'," 127 "`fingerprint` varchar(128) NOT NULL DEFAULT ''," 128 "`signon` datetime DEFAULT NULL," 129 "`server` varchar(255) NOT NULL DEFAULT ''," 130 "`servid` int(11) UNSIGNED NOT NULL DEFAULT '0'," 131 "`uuid` varchar(32) NOT NULL DEFAULT ''," 132 "`oper` enum('Y','N') NOT NULL DEFAULT 'N'," 133 "`away` enum('Y','N') NOT NULL DEFAULT 'N'," 134 "`awaymsg` varchar(255) NOT NULL DEFAULT ''," 135 "`version` varchar(255) NOT NULL DEFAULT ''," 136 "`geocode` varchar(16) NOT NULL DEFAULT ''," 137 "`geocountry` varchar(64) NOT NULL DEFAULT ''," 138 "`georegion` varchar(100) NOT NULL DEFAULT ''," 139 "`geocity` varchar(128) NOT NULL DEFAULT ''," 140 "`locId` INT UNSIGNED," 141 "PRIMARY KEY (`nickid`)," 142 "UNIQUE KEY `nick` (`nick`)," 143 "KEY `servid` (`servid`)" 144 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 145 this->RunQuery(query); 146 } 147 if (!this->HasTable(prefix + "ison")) 148 { 149 query = "CREATE TABLE `" + prefix + "ison` (" 150 "`nickid` int(11) unsigned NOT NULL default '0'," 151 "`chanid` int(11) unsigned NOT NULL default '0'," 152 "`modes` varchar(255) NOT NULL default ''," 153 "PRIMARY KEY (`nickid`,`chanid`)," 154 "KEY `modes` (`modes`)" 155 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 156 this->RunQuery(query); 157 } 158 if (!this->HasTable(prefix + "maxusers")) 159 { 160 query = "CREATE TABLE `" + prefix + "maxusers` (" 161 "`name` VARCHAR(255) NOT NULL," 162 "`maxusers` INT(15) NOT NULL," 163 "`maxtime` DATETIME NOT NULL," 164 "`lastused` DATETIME NOT NULL," 165 "UNIQUE KEY `name` (`name`)" 166 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 167 this->RunQuery(query); 168 } 169 if (this->HasProcedure(prefix + "UserConnect")) 170 this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "UserConnect")); 171 172 if (GeoIPDB.equals_ci("country")) 173 geoquery = "UPDATE `" + prefix + "user` AS u " 174 "JOIN ( SELECT `countrycode`, `countryname` " 175 "FROM `" + prefix + "geoip_country` " 176 "WHERE INET_ATON(ip_) <= `end` " 177 "AND `start` <= INET_ATON(ip_) " 178 "ORDER BY `end` ASC LIMIT 1 ) as c " 179 "SET u.geocode = c.countrycode, u.geocountry = c.countryname " 180 "WHERE u.nick = nick_; "; 181 else if (GeoIPDB.equals_ci("city")) 182 geoquery = "UPDATE `" + prefix + "user` as u " 183 "JOIN ( SELECT * FROM `" + prefix + "geoip_city_location` " 184 "WHERE `locID` = ( SELECT `locID` " 185 "FROM `" + prefix + "geoip_city_blocks` " 186 "WHERE INET_ATON(ip_) <= `end` " 187 "AND `start` <= INET_ATON(ip_) " 188 "ORDER BY `end` ASC LIMIT 1 ) " 189 ") as l " 190 "SET u.geocode = l.country, " 191 "u.geocity = l.city, " 192 "u.locID = l.locID, " 193 "u.georegion = ( SELECT `regionname` " 194 "FROM `" + prefix + "geoip_city_region` " 195 "WHERE `country` = l.country " 196 "AND `region` = l.region )" 197 "WHERE u.nick = nick_;"; 198 199 query = "CREATE PROCEDURE `" + prefix + "UserConnect`" 200 "(nick_ varchar(255), host_ varchar(255), vhost_ varchar(255), " 201 "chost_ varchar(255), realname_ varchar(255), ip_ varchar(255), " 202 "ident_ varchar(255), vident_ varchar(255), account_ varchar(255), " 203 "secure_ enum('Y','N'), fingerprint_ varchar(255), signon_ int(15), " 204 "server_ varchar(255), uuid_ varchar(32), modes_ varchar(255), " 205 "oper_ enum('Y','N')) " 206 "BEGIN " 207 "DECLARE cur int(15);" 208 "DECLARE max int(15);" 209 "INSERT INTO `" + prefix + "user` " 210 "(nick, host, vhost, chost, realname, ip, ident, vident, account, " 211 "secure, fingerprint, signon, server, uuid, modes, oper) " 212 "VALUES (nick_, host_, vhost_, chost_, realname_, ip_, ident_, vident_, " 213 "account_, secure_, fingerprint_, FROM_UNIXTIME(signon_), server_, " 214 "uuid_, modes_, oper_) " 215 "ON DUPLICATE KEY UPDATE host=VALUES(host), vhost=VALUES(vhost), " 216 "chost=VALUES(chost), realname=VALUES(realname), ip=VALUES(ip), " 217 "ident=VALUES(ident), vident=VALUES(vident), account=VALUES(account), " 218 "secure=VALUES(secure), fingerprint=VALUES(fingerprint), signon=VALUES(signon), " 219 "server=VALUES(server), uuid=VALUES(uuid), modes=VALUES(modes), " 220 "oper=VALUES(oper);" 221 "UPDATE `" + prefix + "user` as `u`, `" + prefix + "server` as `s`" 222 "SET u.servid = s.id, " 223 "s.currentusers = s.currentusers + 1 " 224 "WHERE s.name = server_ AND u.nick = nick_;" 225 "SELECT `currentusers` INTO cur FROM `" + prefix + "server` WHERE name=server_;" 226 "SELECT `maxusers` INTO max FROM `" + prefix + "maxusers` WHERE name=server_;" 227 "IF found_rows() AND cur <= max THEN " 228 "UPDATE `" + prefix + "maxusers` SET lastused=now() WHERE name=server_;" 229 "ELSE " 230 "INSERT INTO `" + prefix + "maxusers` (name, maxusers, maxtime, lastused) " 231 "VALUES ( server_, cur, now(), now() ) " 232 "ON DUPLICATE KEY UPDATE " 233 "name=VALUES(name), maxusers=VALUES(maxusers)," 234 "maxtime=VALUES(maxtime), lastused=VALUES(lastused);" 235 "END IF;" 236 + geoquery + 237 "END"; 238 this->RunQuery(query); 239 240 if (this->HasProcedure(prefix + "ServerQuit")) 241 this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "ServerQuit")); 242 query = "CREATE PROCEDURE " + prefix + "ServerQuit(sname_ varchar(255)) " 243 "BEGIN " 244 /* 1. 245 * remove all users on the splitting server from the ison table 246 */ 247 "DELETE i FROM `" + prefix + "ison` AS i " 248 "INNER JOIN `" + prefix + "server` AS s " 249 "INNER JOIN `" + prefix + "user` AS u " 250 "WHERE i.nickid = u.nickid " 251 "AND u.servid = s.id " 252 "AND s.name = sname_;" 253 254 /* 2. 255 * remove all users on the splitting server from the user table 256 */ 257 "DELETE u FROM `" + prefix + "user` AS u " 258 "INNER JOIN `" + prefix + "server` AS s " 259 "WHERE s.id = u.servid " 260 "AND s.name = sname_;" 261 262 /* 3. 263 * on the splitting server, set usercount = 0, split_time = now(), online = 'N' 264 */ 265 "UPDATE `" + prefix + "server` SET currentusers = 0, split_time = now(), online = 'N' " 266 "WHERE name = sname_;" 267 "END;"; // end of the procedure 268 this->RunQuery(query); 269 270 271 if (this->HasProcedure(prefix + "UserQuit")) 272 this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "UserQuit")); 273 query = "CREATE PROCEDURE `" + prefix + "UserQuit`" 274 "(nick_ varchar(255)) " 275 "BEGIN " 276 /* decrease usercount on the server where the user was on */ 277 "UPDATE `" + prefix + "user` AS `u`, `" + prefix + "server` AS `s` " 278 "SET s.currentusers = s.currentusers - 1 " 279 "WHERE u.nick=nick_ AND u.servid = s.id; " 280 /* remove from all channels where the user was on */ 281 "DELETE i FROM `" + prefix + "ison` AS i " 282 "INNER JOIN `" + prefix + "user` as u " 283 "WHERE u.nick = nick_ " 284 "AND i.nickid = u.nickid;" 285 /* remove the user from the user table */ 286 "DELETE FROM `" + prefix + "user` WHERE nick = nick_; " 287 "END"; 288 this->RunQuery(query); 289 290 if (this->HasProcedure(prefix + "ShutDown")) 291 this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "ShutDown")); 292 query = "CREATE PROCEDURE `" + prefix + "ShutDown`()" 293 "BEGIN " 294 "UPDATE `" + prefix + "server` " 295 "SET currentusers=0, online='N', split_time=now();" 296 "TRUNCATE TABLE `" + prefix + "user`;" 297 "TRUNCATE TABLE `" + prefix + "chan`;" 298 "TRUNCATE TABLE `" + prefix + "ison`;" 299 "END"; 300 this->RunQuery(query); 301 302 if (this->HasProcedure(prefix + "JoinUser")) 303 this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "JoinUser")); 304 query = "CREATE PROCEDURE `"+ prefix + "JoinUser`" 305 "(nick_ varchar(255), channel_ varchar(255), modes_ varchar(255)) " 306 "BEGIN " 307 "DECLARE cur int(15);" 308 "DECLARE max int(15);" 309 "INSERT INTO `" + prefix + "ison` (nickid, chanid, modes) " 310 "SELECT u.nickid, c.chanid, modes_ " 311 "FROM " + prefix + "user AS u, " + prefix + "chan AS c " 312 "WHERE u.nick=nick_ AND c.channel=channel_;" 313 "SELECT count(i.chanid) INTO cur " 314 "FROM `" + prefix + "chan` AS c, " + prefix + "ison AS i " 315 "WHERE i.chanid = c.chanid AND c.channel=channel_;" 316 "SELECT `maxusers` INTO max FROM `" + prefix + "maxusers` WHERE name=channel_;" 317 "IF found_rows() AND cur <= max THEN " 318 "UPDATE `" + prefix + "maxusers` SET lastused=now() WHERE name=channel_;" 319 "ELSE " 320 "INSERT INTO `" + prefix + "maxusers` (name, maxusers, maxtime, lastused) " 321 "VALUES ( channel_, cur, now(), now() ) " 322 "ON DUPLICATE KEY UPDATE " 323 "name=VALUES(name), maxusers=VALUES(maxusers)," 324 "maxtime=VALUES(maxtime), lastused=VALUES(lastused);" 325 "END IF;" 326 "END"; 327 this->RunQuery(query); 328 329 if (this->HasProcedure(prefix + "PartUser")) 330 this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "PartUser")); 331 query = "CREATE PROCEDURE `" + prefix + "PartUser`" 332 "(nick_ varchar(255), channel_ varchar(255)) " 333 "BEGIN " 334 "DELETE i FROM `" + prefix + "ison` AS i " 335 "INNER JOIN `" + prefix + "user` AS u " 336 "INNER JOIN `" + prefix + "chan` AS c " 337 "WHERE i.nickid = u.nickid " 338 "AND u.nick = nick_ " 339 "AND i.chanid = c.chanid " 340 "AND c.channel = channel_;" 341 "END"; 342 this->RunQuery(query); 343 }