From 0abaaba6902a0c0a9137d60a83a659eadef4c2b0 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Mon, 23 Jun 2014 21:09:18 -0700 Subject: [PATCH 1/6] Merge channel libraries into a single table --- lib/database/channels.js | 43 +++++++++++++++++----------------------- lib/database/tables.js | 29 ++++++++++++--------------- lib/database/update.js | 34 ++++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/lib/database/channels.js b/lib/database/channels.js index c8e2702b..8bc97b09 100644 --- a/lib/database/channels.js +++ b/lib/database/channels.js @@ -32,7 +32,6 @@ function initTables(name, owner, callback) { if (err) { dropTable("chan_" + name + "_ranks"); dropTable("chan_" + name + "_ranks"); - dropTable("chan_" + name + "_library"); callback(err, null); return; } @@ -212,31 +211,23 @@ module.exports = { err = e2; } - dropTable("chan_" + name + "_library", function (e3) { + 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 (e4) { - if (err && e4) { - err += "\n" + e4; - } else if (e4) { - err = e4; + 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)); }); }); }); @@ -445,9 +436,10 @@ module.exports = { codec: media.meta.codec }); - db.query("INSERT INTO `chan_" + chan + "_library` (id, title, seconds, type, meta) " + - "VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE id=id", - [media.id, media.title, media.seconds, media.type, meta], callback); + db.query("INSERT INTO `channel_libraries` " + + "(id, title, seconds, type, meta, channel) " + + "VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE id=id", + [media.id, media.title, media.seconds, media.type, meta, chan], callback); }, /** @@ -463,7 +455,7 @@ module.exports = { return; } - db.query("SELECT * FROM `chan_" + chan + "_library` WHERE id=?", [id], + db.query("SELECT * FROM `channel_libraries` WHERE id=? AND channel=?", [id, chan], function (err, rows) { if (err) { callback(err, null); @@ -486,8 +478,8 @@ module.exports = { return; } - db.query("SELECT * FROM `chan_" + chan + "_library` WHERE title LIKE ?", - ["%" + search + "%"], callback); + db.query("SELECT * FROM `channel_libraries` WHERE title LIKE ? AND channel=?", + ["%" + search + "%", chan], callback); }, /** @@ -503,7 +495,8 @@ module.exports = { return; } - db.query("DELETE FROM `chan_" + chan + "_library` WHERE id=?", [id], callback); + db.query("DELETE FROM `channel_libraries` WHERE id=? AND channel=?", + [id, chan], callback); }, /** diff --git a/lib/database/tables.js b/lib/database/tables.js index fad6acee..265441f6 100644 --- a/lib/database/tables.js +++ b/lib/database/tables.js @@ -72,6 +72,17 @@ const TBL_META = "" + "PRIMARY KEY (`key`))" + "CHARACTER SET utf8"; +const TBL_LIBRARIES = "" + + "CREATE TABLE IF NOT EXISTS `channel_libraries` (" + + "`id` VARCHAR(255) NOT NULL," + + "`title` VARCHAR(255) NOT NULL," + + "`seconds` INT NOT NULL," + + "`type` VARCHAR(2) NOT NULL," + + "`meta` TEXT NOT NULL," + + "`channel` VARCHAR(30) NOT NULL," + + "PRIMARY KEY(`id`, `channel`), INDEX(`channel`, `title`)" + + ") CHARACTER SET utf8"; + module.exports.init = function (queryfn, cb) { var tables = { users: TBL_USERS, @@ -81,7 +92,8 @@ module.exports.init = function (queryfn, cb) { user_playlists: TBL_USER_PLAYLISTS, aliases: TBL_ALIASES, stats: TBL_STATS, - meta: TBL_META + meta: TBL_META, + channel_libraries: TBL_LIBRARIES }; var AsyncQueue = require("../asyncqueue"); @@ -111,21 +123,6 @@ module.exports.createChannelTables = function (name, queryfn, cb) { "`name` VARCHAR(20) NOT NULL," + "`rank` INT NOT NULL," + "PRIMARY KEY (`name`)) " + - "CHARACTER SET utf8", createLibraryTable); - }; - - var createLibraryTable = function (err) { - if (err) { - cb(err); - return; - } - queryfn("CREATE TABLE `chan_" + name + "_library` (" + - "`id` VARCHAR(255) NOT NULL," + - "`title` VARCHAR(255) NOT NULL," + - "`seconds` INT NOT NULL," + - "`type` VARCHAR(2) NOT NULL," + - "`meta` TEXT NOT NULL," + - "PRIMARY KEY (`id`))" + "CHARACTER SET utf8", createBansTable); }; diff --git a/lib/database/update.js b/lib/database/update.js index 386694d1..cb754905 100644 --- a/lib/database/update.js +++ b/lib/database/update.js @@ -2,7 +2,7 @@ var db = require("../database"); var Logger = require("../logger"); var Q = require("q"); -const DB_VERSION = 3; +const DB_VERSION = 4; var hasUpdates = []; module.exports.checkVersion = function () { @@ -40,6 +40,8 @@ module.exports.checkVersion = function () { function update(version, cb) { if (version < 3 && hasUpdates.indexOf(2) < 0) { addMetaColumnToLibraries(cb); + } else if (version < 4) { + mergeLibraries(cb); } } @@ -68,3 +70,33 @@ function addMetaColumnToLibraries(cb) { Logger.errlog.log("Adding meta column to library tables failed: " + err); }).done(cb); } + +function mergeLibraries(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$/); + }); + + var queue = []; + rows.forEach(function (table) { + var name = table.match(/chan_(.*?)_library$/)[1]; + queue.push(Q.nfcall(db.query, + "INSERT INTO `channel_libraries` SELECT id, title, seconds, type, meta, ?" + + " AS channel FROM `" + table + "`", [name]) + .then(function () { + Logger.syslog.log("Copied " + table + " to channel_libraries"); + }).catch(function (err) { + Logger.errlog.log("Copying " + table + " to channel_libraries failed: " + + err); + }) + ); + }); + + return Q.all(queue); + }).catch(function (err) { + Logger.errlog.log("Copying libraries to channel_libraries failed: " + err); + }).done(cb); +} From 4afd69b2fb7d98d91a6e78808e67811348efcff9 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Mon, 23 Jun 2014 21:40:40 -0700 Subject: [PATCH 2/6] 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); } From c768d9595c4bc6547f477ec4c1b02fca901f9d17 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Mon, 23 Jun 2014 22:10:15 -0700 Subject: [PATCH 3/6] 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); +} From 36c4e41131544944010f8709c079afc7f179db81 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Mon, 23 Jun 2014 22:15:57 -0700 Subject: [PATCH 4/6] Add console command for deleting old channel tables --- index.js | 6 ++++++ lib/database/update.js | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 127be83f..03514bfb 100644 --- a/index.js +++ b/index.js @@ -47,5 +47,11 @@ function handleLine(line) { } else { Logger.syslog.log("Failed to invoke GC: node started without --expose-gc"); } + } else if (line === "/delete_old_tables") { + require("./lib/database/update").deleteOldChannelTables(function (err) { + if (!err) { + Logger.syslog.log("Deleted old channel tables"); + } + }); } } diff --git a/lib/database/update.js b/lib/database/update.js index ce2b4b76..fcae7fa8 100644 --- a/lib/database/update.js +++ b/lib/database/update.js @@ -26,8 +26,7 @@ module.exports.checkVersion = function () { var next = function () { hasUpdates.push(v); if (v < DB_VERSION) { - update(v++, next); - } else { + update(v++, next); } else { db.query("UPDATE `meta` SET `value`=? WHERE `key`='db_version'", [DB_VERSION]); } @@ -45,7 +44,11 @@ function update(version, cb) { Q.fcall(mergeChannelLibraries), Q.fcall(mergeChannelRanks), Q.fcall(mergeChannelBans) - ]).done(cb) + ]).done(function () { + Logger.syslog.log("Merged channel tables. Please verify that everything " + + "is working correctly, and then type '/delete_old_tables'" + + " into the CyTube process to remove the unused tables."); + }) } } @@ -182,3 +185,35 @@ function mergeChannelBans(cb) { } }).done(cb); } + +module.exports.deleteOldChannelTables = function (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_(.*?)_(library|ranks|bans)$/); + }); + + var queue = []; + rows.forEach(function (table) { + queue.push(Q.nfcall(db.query, "DROP TABLE `" + table + "`") + .then(function () { + Logger.syslog.log("Deleted " + table); + }).catch(function (err) { + Logger.errlog.log("Deleting " + table + " failed: " + err); + if (err.stack) { + Logger.errlog.log(err.stack); + } + }) + ); + }); + + return Q.all(queue); + }).catch(function (err) { + Logger.errlog.log("Deleting old tables failed: " + err); + if (err.stack) { + Logger.errlog.log(err.stack); + } + }).done(cb); +}; From f44c9ce51bc78b4b0572c6ac3904ca497860df37 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Tue, 24 Jun 2014 20:28:04 -0700 Subject: [PATCH 5/6] Fix updater --- lib/database/update.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/database/update.js b/lib/database/update.js index fcae7fa8..a871766e 100644 --- a/lib/database/update.js +++ b/lib/database/update.js @@ -25,8 +25,10 @@ module.exports.checkVersion = function () { } var next = function () { hasUpdates.push(v); + Logger.syslog.log("Updated database to version " + v); if (v < DB_VERSION) { - update(v++, next); } else { + update(v++, next); + } else { db.query("UPDATE `meta` SET `value`=? WHERE `key`='db_version'", [DB_VERSION]); } @@ -40,14 +42,15 @@ function update(version, cb) { if (version < 3 && hasUpdates.indexOf(2) < 0) { addMetaColumnToLibraries(cb); } else if (version < 4) { - Q.all([ - Q.fcall(mergeChannelLibraries), - Q.fcall(mergeChannelRanks), - Q.fcall(mergeChannelBans) + Q.allSettled([ + Q.nfcall(mergeChannelLibraries), + Q.nfcall(mergeChannelRanks), + Q.nfcall(mergeChannelBans) ]).done(function () { Logger.syslog.log("Merged channel tables. Please verify that everything " + "is working correctly, and then type '/delete_old_tables'" + " into the CyTube process to remove the unused tables."); + cb(); }) } } @@ -111,7 +114,7 @@ function mergeChannelLibraries(cb) { if (err.stack) { Logger.errlog.log(err.stack); } - }).done(cb); + }).done(function () { cb(null); }); } function mergeChannelRanks(cb) { @@ -147,7 +150,7 @@ function mergeChannelRanks(cb) { if (err.stack) { Logger.errlog.log(err.stack); } - }).done(cb); + }).done(function () { cb(null); }); } function mergeChannelBans(cb) { @@ -183,7 +186,7 @@ function mergeChannelBans(cb) { if (err.stack) { Logger.errlog.log(err.stack); } - }).done(cb); + }).done(function () { cb(null); }); } module.exports.deleteOldChannelTables = function (cb) { From 3dcdaf30451a14a8f9afc875042c0674c2908885 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Wed, 25 Jun 2014 20:13:03 -0700 Subject: [PATCH 6/6] Update version number --- lib/server.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/server.js b/lib/server.js index 70dfeb70..56890a98 100644 --- a/lib/server.js +++ b/lib/server.js @@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -const VERSION = "3.2.2"; +const VERSION = "3.3.0"; var singleton = null; var Config = require("./config"); diff --git a/package.json b/package.json index b6337ca6..05785221 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Calvin Montgomery", "name": "CyTube", "description": "Online media synchronizer and chat", - "version": "3.2.2", + "version": "3.3.0", "repository": { "url": "http://github.com/calzoneman/sync" },