From 4afd69b2fb7d98d91a6e78808e67811348efcff9 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Mon, 23 Jun 2014 21:40:40 -0700 Subject: [PATCH] Merge channel ranks tables --- lib/channel/kickban.js | 2 +- lib/database/channels.js | 77 +++++++++++++++------------------------- lib/database/tables.js | 23 ++++++------ lib/database/update.js | 51 ++++++++++++++++++++++++-- 4 files changed, 89 insertions(+), 64 deletions(-) diff --git a/lib/channel/kickban.js b/lib/channel/kickban.js index 5771ed2b..b645a71d 100644 --- a/lib/channel/kickban.js +++ b/lib/channel/kickban.js @@ -310,7 +310,7 @@ KickBanModule.prototype.banIP = function (actor, ip, name, reason, cb) { return error("You do not have ban permissions on this channel"); } - Q.nfcall(Account.rankForIP, ip).then(function (rank) { + Q.nfcall(Account.rankForIP, ip, { channel: chan.name }).then(function (rank) { if (rank >= actor.account.effectiveRank) { throw "You don't have permission to ban IP " + masked; } diff --git a/lib/database/channels.js b/lib/database/channels.js index 8bc97b09..582368ff 100644 --- a/lib/database/channels.js +++ b/lib/database/channels.js @@ -30,8 +30,6 @@ function initTables(name, owner, callback) { module.exports.setRank(name, owner, rank, function (err) { if (err) { - dropTable("chan_" + name + "_ranks"); - dropTable("chan_" + name + "_ranks"); callback(err, null); return; } @@ -203,32 +201,24 @@ module.exports = { return; } - dropTable("chan_" + name + "_ranks", function (err) { - dropTable("chan_" + name + "_bans", function (e2) { - if (err && e2) { - err += "\n" + e2; - } else if (e2) { - err = e2; + dropTable("chan_" + name + "_bans", function (err) { + db.query("DELETE FROM `channels` WHERE name=?", [name], + function (e3) { + if (err && e3) { + err += "\n" + e3; + } else if (e3) { + err = e3; } - db.query("DELETE FROM `channels` WHERE name=?", [name], - function (e3) { - if (err && e3) { - err += "\n" + e3; - } else if (e3) { - err = e3; + fs.unlink(path.join(__dirname, "..", "..", "chandump", name), + function (err) { + if (err && err.code !== "ENOENT") { + Logger.errlog.log("Deleting chandump failed:"); + Logger.errlog.log(err); } - - fs.unlink(path.join(__dirname, "..", "..", "chandump", name), - function (err) { - if (err && err.code !== "ENOENT") { - Logger.errlog.log("Deleting chandump failed:"); - Logger.errlog.log(err); - } - }); - - callback(err, !Boolean(err)); }); + + callback(err, !Boolean(err)); }); }); }, @@ -304,8 +294,8 @@ module.exports = { return; } - db.query("SELECT name,rank FROM `chan_" + chan + "_ranks` WHERE name=?", - [name], + db.query("SELECT * FROM `channel_ranks` WHERE name=? AND channel=?", + [name, chan], function (err, rows) { if (err) { callback(err, -1); @@ -335,8 +325,12 @@ module.exports = { } var replace = "(" + names.map(function () { return "?"; }).join(",") + ")"; - db.query("SELECT name,rank FROM `chan_" + chan + "_ranks` WHERE name IN " + - replace, names, + + /* Last substitution is the channel to select ranks for */ + names.push(chan); + + db.query("SELECT * FROM `channel_ranks` WHERE name IN " + + replace + " AND channel=?", names, function (err, rows) { if (err) { callback(err, []); @@ -360,7 +354,7 @@ module.exports = { return; } - db.query("SELECT name,rank FROM `chan_" + chan + "_ranks` WHERE 1", callback); + db.query("SELECT * FROM `channel_ranks` WHERE channel=?", [chan], callback); }, /** @@ -381,25 +375,9 @@ module.exports = { return; } - db.query("INSERT INTO `chan_" + chan + "_ranks` (name, rank) VALUES (?, ?) " + - "ON DUPLICATE KEY UPDATE rank=?", [name, rank, rank], callback); - }, - - /** - * Inserts a new user rank entry without clobbering an existing one - */ - newRank: function (chan, name, rank, callback) { - if (typeof callback !== "function") { - callback = blackHole; - } - - if (!valid(chan)) { - callback("Invalid channel name", null); - return; - } - - db.query("INSERT INTO `chan_" + chan + "_ranks` (name, rank) VALUES (?, ?) " + - "ON DUPLICATE KEY UPDATE rank=rank", [name, rank], callback); + db.query("INSERT INTO `channel_ranks` VALUES (?, ?, ?) " + + "ON DUPLICATE KEY UPDATE rank=?", + [name, rank, chan, rank, chan], callback); }, /** @@ -415,7 +393,8 @@ module.exports = { return; } - db.query("DELETE FROM `chan_" + chan + "_ranks` WHERE name=?", [name], callback); + db.query("DELETE FROM `channel_ranks` WHERE name=? AND channel=?", [name, chan], + callback); }, /** diff --git a/lib/database/tables.js b/lib/database/tables.js index 265441f6..9958963c 100644 --- a/lib/database/tables.js +++ b/lib/database/tables.js @@ -83,17 +83,26 @@ const TBL_LIBRARIES = "" + "PRIMARY KEY(`id`, `channel`), INDEX(`channel`, `title`)" + ") CHARACTER SET utf8"; +const TBL_RANKS = "" + + "CREATE TABLE IF NOT EXISTS `channel_ranks` (" + + "`name` VARCHAR(20) NOT NULL," + + "`rank` INT NOT NULL," + + "`channel` VARCHAR(30) NOT NULL," + + "PRIMARY KEY(`name`, `channel`)" + + ") CHARACTER SET utf8"; + module.exports.init = function (queryfn, cb) { var tables = { users: TBL_USERS, channels: TBL_CHANNELS, + channel_libraries: TBL_LIBRARIES, + channel_ranks: TBL_RANKS, global_bans: TBL_GLOBAL_BANS, password_reset: TBL_PASSWORD_RESET, user_playlists: TBL_USER_PLAYLISTS, aliases: TBL_ALIASES, stats: TBL_STATS, - meta: TBL_META, - channel_libraries: TBL_LIBRARIES + meta: TBL_META }; var AsyncQueue = require("../asyncqueue"); @@ -118,14 +127,6 @@ module.exports.init = function (queryfn, cb) { }; module.exports.createChannelTables = function (name, queryfn, cb) { - var createRanksTable = function () { - queryfn("CREATE TABLE `chan_" + name + "_ranks` (" + - "`name` VARCHAR(20) NOT NULL," + - "`rank` INT NOT NULL," + - "PRIMARY KEY (`name`)) " + - "CHARACTER SET utf8", createBansTable); - }; - var createBansTable = function (err) { if (err) { cb(err); @@ -141,5 +142,5 @@ module.exports.createChannelTables = function (name, queryfn, cb) { "CHARACTER SET utf8", cb); }; - createRanksTable(); + createBansTable(); }; diff --git a/lib/database/update.js b/lib/database/update.js index cb754905..a88874a6 100644 --- a/lib/database/update.js +++ b/lib/database/update.js @@ -41,7 +41,10 @@ function update(version, cb) { if (version < 3 && hasUpdates.indexOf(2) < 0) { addMetaColumnToLibraries(cb); } else if (version < 4) { - mergeLibraries(cb); + Q.all([ + Q.fcall(mergeChannelLibraries), + Q.fcall(mergeChannelRanks) + ]).done(cb) } } @@ -71,13 +74,13 @@ function addMetaColumnToLibraries(cb) { }).done(cb); } -function mergeLibraries(cb) { +function mergeChannelLibraries(cb) { Q.nfcall(db.query, "SHOW TABLES") .then(function (rows) { rows = rows.map(function (r) { return r[Object.keys(r)[0]]; }).filter(function (r) { - return r.match(/_library$/); + return r.match(/chan_(.*)?_library$/); }); var queue = []; @@ -91,6 +94,9 @@ function mergeLibraries(cb) { }).catch(function (err) { Logger.errlog.log("Copying " + table + " to channel_libraries failed: " + err); + if (err.stack) { + Logger.errlog.log(err.stack); + } }) ); }); @@ -98,5 +104,44 @@ function mergeLibraries(cb) { return Q.all(queue); }).catch(function (err) { Logger.errlog.log("Copying libraries to channel_libraries failed: " + err); + if (err.stack) { + Logger.errlog.log(err.stack); + } + }).done(cb); +} + +function mergeChannelRanks(cb) { + Q.nfcall(db.query, "SHOW TABLES") + .then(function (rows) { + rows = rows.map(function (r) { + return r[Object.keys(r)[0]]; + }).filter(function (r) { + return r.match(/chan_(.*?)_ranks$/); + }); + + var queue = []; + rows.forEach(function (table) { + var name = table.match(/chan_(.*?)_ranks$/)[1]; + queue.push(Q.nfcall(db.query, + "INSERT INTO `channel_ranks` SELECT name, rank, ?" + + " AS channel FROM `" + table + "`", [name]) + .then(function () { + Logger.syslog.log("Copied " + table + " to channel_ranks"); + }).catch(function (err) { + Logger.errlog.log("Copying " + table + " to channel_ranks failed: " + + err); + if (err.stack) { + Logger.errlog.log(err.stack); + } + }) + ); + }); + + return Q.all(queue); + }).catch(function (err) { + Logger.errlog.log("Copying ranks to channel_ranks failed: " + err); + if (err.stack) { + Logger.errlog.log(err.stack); + } }).done(cb); }