From c768d9595c4bc6547f477ec4c1b02fca901f9d17 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Mon, 23 Jun 2014 22:10:15 -0700 Subject: [PATCH] Merge ban tables, fix channel create/delete operations --- lib/database/channels.js | 177 +++++++++++++++++++++------------------ lib/database/tables.js | 32 +++---- lib/database/update.js | 39 ++++++++- 3 files changed, 146 insertions(+), 102 deletions(-) diff --git a/lib/database/channels.js b/lib/database/channels.js index 582368ff..dd68f083 100644 --- a/lib/database/channels.js +++ b/lib/database/channels.js @@ -19,25 +19,6 @@ function initTables(name, owner, callback) { return; } - tables.createChannelTables(name, db.query.bind(db), function (err) { - db.users.getGlobalRank(owner, function (err, rank) { - if (err) { - callback(err, null); - return; - } - - rank = Math.max(rank, 5); - - module.exports.setRank(name, owner, rank, function (err) { - if (err) { - callback(err, null); - return; - } - - callback(null, true); - }); - }); - }); } module.exports = { @@ -174,14 +155,21 @@ module.exports = { return; } - initTables(name, owner, function (err, res) { + db.users.getGlobalRank(owner, function (err, rank) { if (err) { - db.query("DELETE FROM `channels` WHERE name=?", [name]); callback(err, null); return; } - callback(null, { - name: name + + rank = Math.max(rank, 5); + + module.exports.setRank(name, owner, rank, function (err) { + if (err) { + callback(err, null); + return; + } + + callback(null, { name: name }); }); }); }); @@ -201,25 +189,35 @@ module.exports = { return; } - 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 (err) { + + module.exports.deleteBans(name, function (err) { + if (err) { + Logger.errlog.log("Failed to delete bans for " + name + ": " + 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)); }); + + module.exports.deleteLibrary(name, function (err) { + if (err) { + Logger.errlog.log("Failed to delete library for " + name + ": " + err); + } + }); + + module.exports.deleteAllRanks(name, function (err) { + if (err) { + Logger.errlog.log("Failed to delete ranks for " + name + ": " + 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)); }); }, @@ -397,6 +395,22 @@ module.exports = { callback); }, + /** + * Removes all ranks for a channel + */ + deleteAllRanks: function (chan, callback) { + if (typeof callback !== "function") { + callback = blackHole; + } + + if (!valid(chan)) { + callback("Invalid channel name", null); + return; + } + + db.query("DELETE FROM `channel_ranks` WHERE channel=?", [chan], callback); + }, + /** * Adds a media item to the library */ @@ -478,6 +492,22 @@ module.exports = { [id, chan], callback); }, + /** + * Deletes all library entries for a channel + */ + deleteLibrary: function (chan, callback) { + if (typeof callback !== "function") { + callback = blackHole; + } + + if (!valid(chan)) { + callback("Invalid channel name", null); + return; + } + + db.query("DELETE FROM `channel_libraries` WHERE channel=?", [chan], callback); + }, + /** * Add a ban to the banlist */ @@ -491,8 +521,9 @@ module.exports = { return; } - db.query("INSERT INTO `chan_" + chan + "_bans` (ip, name, reason, bannedby) " + - "VALUES (?, ?, ?, ?)", [ip, name, note, bannedby], callback); + db.query("INSERT INTO `channel_bans` (ip, name, reason, bannedby, channel) " + + "VALUES (?, ?, ?, ?, ?)", + [ip, name, note, bannedby, chan], callback); }, /** @@ -511,8 +542,8 @@ module.exports = { var range = util.getIPRange(ip); var wrange = util.getWideIPRange(ip); - db.query("SELECT * FROM `chan_" + chan + "_bans` WHERE ip IN (?, ?, ?)", - [ip, range, wrange], + db.query("SELECT * FROM `channel_bans` WHERE ip IN (?, ?, ?) AND channel=?", + [ip, range, wrange, chan], function (err, rows) { callback(err, err ? false : rows.length > 0); }); @@ -531,7 +562,7 @@ module.exports = { return; } - db.query("SELECT * FROM `chan_" + chan + "_bans` WHERE name=?", [name], + db.query("SELECT * FROM `channel_bans` WHERE name=? AND channel=?", [name, chan], function (err, rows) { callback(err, err ? false : rows.length > 0); }); @@ -550,41 +581,7 @@ module.exports = { return; } - db.query("SELECT * FROM `chan_" + chan + "_bans` WHERE 1", callback); - }, - - /** - * Removes a ban from the banlist - */ - unbanName: function (chan, name, callback) { - if (typeof callback !== "function") { - callback = blackHole; - } - - if (!valid(chan)) { - callback("Invalid channel name", null); - return; - } - - db.query("DELETE FROM `chan_" + chan + "_bans` WHERE ip='*' AND name=?", - [name], callback); - }, - - /** - * Removes a ban from the banlist - */ - unbanIP: function (chan, ip, callback) { - if (typeof callback !== "function") { - callback = blackHole; - } - - if (!valid(chan)) { - callback("Invalid channel name", null); - return; - } - - db.query("DELETE FROM `chan_" + chan + "_bans` WHERE ip=?", - [ip], callback); + db.query("SELECT * FROM `channel_bans` WHERE channel=?", [chan], callback); }, /** @@ -600,7 +597,23 @@ module.exports = { return; } - db.query("DELETE FROM `chan_" + chan + "_bans` WHERE id=?", - [id], callback); + db.query("DELETE FROM `channel_bans` WHERE id=? AND channel=?", + [id, chan], callback); + }, + + /** + * Removes all bans from a channel + */ + deleteBans: function (chan, id, callback) { + if (typeof callback !== "function") { + callback = blackHole; + } + + if (!valid(chan)) { + callback("Invalid channel name", null); + return; + } + + db.query("DELETE FROM `channel_bans` WHERE channel=?", [chan], callback); } }; diff --git a/lib/database/tables.js b/lib/database/tables.js index 9958963c..4fbd7a09 100644 --- a/lib/database/tables.js +++ b/lib/database/tables.js @@ -91,12 +91,25 @@ const TBL_RANKS = "" + "PRIMARY KEY(`name`, `channel`)" + ") CHARACTER SET utf8"; +const TBL_BANS = "" + + "CREATE TABLE IF NOT EXISTS `channel_bans` (" + + "`id` INT NOT NULL AUTO_INCREMENT," + + "`ip` VARCHAR(39) NOT NULL," + + "`name` VARCHAR(20) NOT NULL," + + "`bannedby` VARCHAR(20) NOT NULL," + + "`reason` VARCHAR(255) NOT NULL," + + "`channel` VARCHAR(30) NOT NULL," + + "PRIMARY KEY (`id`, `channel`), UNIQUE (`name`, `ip`, `channel`), " + + "INDEX (`ip`, `channel`), INDEX (`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, + channel_bans: TBL_BANS, global_bans: TBL_GLOBAL_BANS, password_reset: TBL_PASSWORD_RESET, user_playlists: TBL_USER_PLAYLISTS, @@ -125,22 +138,3 @@ module.exports.init = function (queryfn, cb) { cb(hasError); }); }; - -module.exports.createChannelTables = function (name, queryfn, cb) { - var createBansTable = function (err) { - if (err) { - cb(err); - return; - } - queryfn("CREATE TABLE `chan_" + name + "_bans` (" + - "`id` INT NOT NULL AUTO_INCREMENT," + - "`ip` VARCHAR(39) NOT NULL," + - "`name` VARCHAR(20) NOT NULL," + - "`bannedby` VARCHAR(20) NOT NULL," + - "`reason` VARCHAR(255) NOT NULL," + - "PRIMARY KEY (`id`), UNIQUE (`name`, `ip`))" + - "CHARACTER SET utf8", cb); - }; - - createBansTable(); -}; diff --git a/lib/database/update.js b/lib/database/update.js index a88874a6..ce2b4b76 100644 --- a/lib/database/update.js +++ b/lib/database/update.js @@ -43,7 +43,8 @@ function update(version, cb) { } else if (version < 4) { Q.all([ Q.fcall(mergeChannelLibraries), - Q.fcall(mergeChannelRanks) + Q.fcall(mergeChannelRanks), + Q.fcall(mergeChannelBans) ]).done(cb) } } @@ -145,3 +146,39 @@ function mergeChannelRanks(cb) { } }).done(cb); } + +function mergeChannelBans(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_(.*?)_bans$/); + }); + + var queue = []; + rows.forEach(function (table) { + var name = table.match(/chan_(.*?)_bans$/)[1]; + queue.push(Q.nfcall(db.query, + "INSERT INTO `channel_bans` SELECT id, ip, name, bannedby, reason, ?" + + " AS channel FROM `" + table + "`", [name]) + .then(function () { + Logger.syslog.log("Copied " + table + " to channel_bans"); + }).catch(function (err) { + Logger.errlog.log("Copying " + table + " to channel_bans failed: " + + err); + if (err.stack) { + Logger.errlog.log(err.stack); + } + }) + ); + }); + + return Q.all(queue); + }).catch(function (err) { + Logger.errlog.log("Copying ranks to channel_bans failed: " + err); + if (err.stack) { + Logger.errlog.log(err.stack); + } + }).done(cb); +}