Fix db key issue for bans - run node update.js 2013-08-21-banfix

This commit is contained in:
calzoneman 2013-08-21 16:09:28 -05:00
parent d5ebf1ad4e
commit 6d47a94fe9
2 changed files with 75 additions and 6 deletions

View file

@ -366,7 +366,7 @@ Database.prototype.registerChannel = function (name, owner, callback) {
"`ip` VARCHAR(15) NOT NULL,",
"`name` VARCHAR(32) NOT NULL,",
"`banner` VARCHAR(32) NOT NULL,",
"PRIMARY KEY (`ip`))",
"PRIMARY KEY (`ip`, `name`))",
"ENGINE = MyISAM ",
"CHARACTER SET utf8;"].join("");
@ -570,10 +570,10 @@ Database.prototype.addToLibrary = function (channame, media, callback) {
return;
}
// use INSERT IGNORE to prevent errors from adding duplicates
var query = "INSERT IGNORE INTO `chan_" + channame + "_library` " +
var query = "INSERT INTO `chan_" + channame + "_library` " +
"(id, title, seconds, type) " +
"VALUES (?, ?, ?, ?)";
"VALUES (?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE id=id";
var params = [
media.id,
media.title,
@ -648,7 +648,8 @@ Database.prototype.addChannelBan = function (channame, ip, name, banBy,
}
var query = "INSERT INTO `chan_" + channame + "_bans`" +
"(ip, name, banner) VALUES (?, ?, ?)";
"(ip, name, banner) VALUES (?, ?, ?) " +
"ON DUPLICATE KEY UPDATE ip=ip";
self.query(query, [ip, name, banBy], callback);
};

View file

@ -2,7 +2,8 @@ var Config = require("./config.js");
var Database = require("./database.js");
var updates = {
"2013-08-20-utf8fix": fixDBUnicode
"2013-08-20-utf8fix": fixDBUnicode,
"2013-08-21-banfix": fixChannelBanKey
};
var x = {};
@ -23,6 +24,25 @@ Config.load(x, "cfg.json", function () {
fn(db);
});
/*
2013-08-20
This function iterates over tables in the database and converts the
encoding on each to UTF-8.
Furthermore, it does the following to convert channel libraries in
a way such that UTF-8 titles stored in other encodings (e.g. latin1)
are preserved as UTF-8:
1. Change the `title` column to BLOB (unencoded)
2. Change the table character set to utf8
3. Change the `title` column to VARCHAR(255) CHARACTER SET utf8
This corrects an encoding issue that was exposed when switching to
node-mysql. mysql-libmysqlclient ignored database encoding and assumed
the data was UTF-8.
*/
function fixDBUnicode(db) {
db.query("SHOW TABLES", function (err, res) {
if(err) {
@ -110,3 +130,51 @@ function fixDBUnicode(db) {
}, 1000);
});
}
/*
2013-08-21
This function iterates over channel ban tables and corrects the
PRIMARY KEY. Previously, the table was defined with PRIMARY KEY (ip),
but in reality, (ip, name) should be pairwise unique.
This corrects the issue where only one name ban can exist in the table
because of the `ip` field "*" being unique.
*/
function fixChannelBanKey(db) {
db.query("SHOW TABLES", function (err, res) {
if(err) {
console.log("SEVERE: SHOW TABLES failed");
return;
}
var count = res.length;
res.forEach(function (r) {
var k = Object.keys(r)[0];
if(!r[k].match(/^chan_[\w-_]{1,30}_bans$/)) {
count--;
return;
}
db.query("ALTER TABLE `" + r[k] + "` DROP PRIMARY KEY, ADD PRIMARY KEY (ip, name)", function (err, res) {
count--;
if(err) {
console.log("FAILED: " + r[k]);
return;
}
console.log("Fixed " + r[k]);
});
});
setInterval(function () {
if(count == 0) {
console.log("Done");
process.exit(0);
}
}, 1000);
});
}