Start refactoring database channels
This commit is contained in:
parent
a14363a845
commit
db5dcf86f7
189
lib/database.js
189
lib/database.js
|
@ -287,104 +287,6 @@ module.exports.clearGlobalIPBan = function (ip, callback) {
|
|||
|
||||
/* REGION channels */
|
||||
|
||||
module.exports.searchChannel = function (field, value, callback) {
|
||||
if(typeof callback !== "function")
|
||||
return;
|
||||
|
||||
var query = "SELECT * FROM channels WHERE ";
|
||||
if(field === "owner")
|
||||
query += "owner LIKE ?";
|
||||
else if(field === "name")
|
||||
query += "name LIKE ?";
|
||||
|
||||
module.exports.query(query, ["%" + value + "%"], callback);
|
||||
};
|
||||
|
||||
module.exports.channelExists = function (name, callback) {
|
||||
if(typeof callback !== "function")
|
||||
return;
|
||||
if(!$util.isValidChannelName(name)) {
|
||||
callback("Invalid channel name", null);
|
||||
return;
|
||||
}
|
||||
|
||||
var query = "SELECT name FROM channels WHERE name=?";
|
||||
module.exports.query(query, [name], function (err, res) {
|
||||
callback(err, res.length > 0);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.registerChannel = function (name, owner, callback) {
|
||||
if(typeof callback !== "function")
|
||||
callback = blackHole;
|
||||
|
||||
if(!$util.isValidChannelName(name)) {
|
||||
callback("Invalid channel name", null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Messy, but I can't think of a better async solution atm
|
||||
var query = "SELECT * FROM channels WHERE name=?";
|
||||
module.exports.query(query, [name], function (err, res) {
|
||||
if(!err && res.length > 0) {
|
||||
callback("Channel already exists", null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Library table
|
||||
query = ["CREATE TABLE `chan_" + name + "_library` (",
|
||||
"`id` VARCHAR(255) NOT NULL,",
|
||||
"`title` VARCHAR(255) NOT NULL,",
|
||||
"`seconds` INT NOT NULL,",
|
||||
"`type` VARCHAR(2) NOT NULL,",
|
||||
"PRIMARY KEY (`id`))",
|
||||
"ENGINE = MyISAM ",
|
||||
"CHARACTER SET utf8;"].join("");
|
||||
module.exports.query(query, function (err, res) {
|
||||
if(err) {
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Rank table
|
||||
query = ["CREATE TABLE `chan_" + name + "_ranks` (",
|
||||
"`name` VARCHAR(32) NOT NULL,",
|
||||
"`rank` INT NOT NULL,",
|
||||
"UNIQUE (`name`))",
|
||||
"ENGINE = MyISAM ",
|
||||
"CHARACTER SET utf8;"].join("");
|
||||
|
||||
module.exports.query(query, function (err, res) {
|
||||
if(err) {
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ban table
|
||||
query = ["CREATE TABLE `chan_" + name + "_bans` (",
|
||||
"`ip` VARCHAR(15) NOT NULL,",
|
||||
"`name` VARCHAR(32) NOT NULL,",
|
||||
"`banner` VARCHAR(32) NOT NULL,",
|
||||
"PRIMARY KEY (`ip`, `name`))",
|
||||
"ENGINE = MyISAM ",
|
||||
"CHARACTER SET utf8;"].join("");
|
||||
|
||||
module.exports.query(query, function (err, res) {
|
||||
if(err) {
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
query = "INSERT INTO channels VALUES (NULL, ?, ?)";
|
||||
module.exports.query(query, [name, owner], function (err, res) {
|
||||
callback(err, res);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.loadChannelData = function (chan, callback) {
|
||||
if(typeof callback !== "function")
|
||||
callback = blackHole;
|
||||
|
@ -443,97 +345,6 @@ module.exports.loadChannelData = function (chan, callback) {
|
|||
});
|
||||
};
|
||||
|
||||
module.exports.dropChannel = function (name, callback) {
|
||||
if(typeof callback !== "function")
|
||||
callback = blackHole;
|
||||
|
||||
if(!$util.isValidChannelName(name)) {
|
||||
callback("Invalid channel name", null);
|
||||
return;
|
||||
}
|
||||
|
||||
var query = "DROP TABLE `chan_?_bans`,`chan_?_ranks`,`chan_?_library`"
|
||||
.replace(/\?/g, name);
|
||||
|
||||
module.exports.query(query, function (err, res) {
|
||||
if(err) {
|
||||
Logger.errlog.log("! Failed to drop channel tables for "+name);
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
query = "DELETE FROM channels WHERE name=?";
|
||||
module.exports.query(query, [name], function (err, res) {
|
||||
callback(err, res);
|
||||
if(err) {
|
||||
Logger.errlog.log("! Failed to delete channel "+name);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.getChannelRank = function (channame, name, callback) {
|
||||
if(typeof callback !== "function")
|
||||
return;
|
||||
|
||||
if(!$util.isValidChannelName(channame)) {
|
||||
callback("Invalid channel name", null);
|
||||
return;
|
||||
}
|
||||
|
||||
var query = "SELECT name, rank FROM `chan_" + channame + "_ranks`" +
|
||||
"WHERE name=?";
|
||||
|
||||
module.exports.query(query, [name], function (err, res) {
|
||||
if(err) {
|
||||
Logger.errlog.log("! Failed to lookup " + channame + " ranks");
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if(res.length == 0)
|
||||
callback(null, 0);
|
||||
else
|
||||
callback(null, res[0].rank);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.listChannelUserRanks = function (channame, names,
|
||||
callback) {
|
||||
if(typeof callback !== "function")
|
||||
return;
|
||||
|
||||
if(!$util.isValidChannelName(channame)) {
|
||||
callback("Invalid channel name", null);
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof names === "string")
|
||||
names = [names];
|
||||
|
||||
// Build the query template (?, ?, ?, ?, ...)
|
||||
var nlist = [];
|
||||
for(var i in names)
|
||||
nlist.push("?");
|
||||
nlist = "(" + nlist.join(",") + ")";
|
||||
|
||||
var query = "SELECT name, rank FROM `chan_" + channame + "_ranks`" +
|
||||
"WHERE name IN " + nlist;
|
||||
|
||||
module.exports.query(query, names, function (err, res) {
|
||||
if(err) {
|
||||
Logger.errlog.log("! Failed to lookup " + channame + " ranks");
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
for(var i in res)
|
||||
res[i] = res[i].rank;
|
||||
|
||||
callback(null, res);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.setChannelRank = function (channame, name, rank, callback) {
|
||||
if(typeof callback !== "function")
|
||||
callback = blackHole;
|
||||
|
|
294
lib/database/channels.js
Normal file
294
lib/database/channels.js
Normal file
|
@ -0,0 +1,294 @@
|
|||
var db = require("../database");
|
||||
var $util = require("../utilities");
|
||||
|
||||
var blackHole = function () { };
|
||||
|
||||
function dropTable(name, callback) {
|
||||
db.query("DROP TABLE `" + name + "`");
|
||||
}
|
||||
|
||||
function createRanksTable(name, callback) {
|
||||
db.query("CREATE TABLE `chan_" + name + "_ranks` (" +
|
||||
"`name` VARCHAR(20) NOT NULL," +
|
||||
"`rank` INT NOT NULL," +
|
||||
"PRIMARY KEY (`name`)) " +
|
||||
"CHARACTER SET utf8", callback);
|
||||
}
|
||||
|
||||
function createLibraryTable(name, callback) {
|
||||
db.query("CREATE TABLE `chan_" + name + "_library` (" +
|
||||
"`id` VARCHAR(255) NOT NULL," +
|
||||
"`title` VARCHAR(255) NOT NULL," +
|
||||
"`seconds` INT NOT NULL,"
|
||||
"`type` VARCHAR(2) NOT NULL," +
|
||||
"PRIMARY KEY (`id`))" +
|
||||
"CHARACTER SET utf8", callback);
|
||||
}
|
||||
|
||||
function createBansTable(name, callback) {
|
||||
db.query("CREATE TABLE `chan_" + name + "_bans` (" +
|
||||
"`ip` VARCHAR(39) NOT NULL," +
|
||||
"`name` VARCHAR(20) NOT NULL," +
|
||||
"`bannedby` VARCHAR(20) NOT NULL," +
|
||||
"`reason` VARCHAR(255) NOT NULL," +
|
||||
"PRIMARY KEY (`ip`, `name`))" +
|
||||
"CHARACTER SET utf8", callback);
|
||||
}
|
||||
|
||||
function initTables(name, owner, callback) {
|
||||
createRanksTable(name, function (err) {
|
||||
if (err) {
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO add owner to ranks table
|
||||
|
||||
createLibraryTable(name, function (err) {
|
||||
if (err) {
|
||||
dropTable("chan_" + name + "_ranks");
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
createBansTable(name, function (err) {
|
||||
if (err) {
|
||||
dropTable("chan_" + name + "_ranks");
|
||||
dropTable("chan_" + name + "_library");
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Initialize the channels table
|
||||
*/
|
||||
init: function () {
|
||||
db.query("CREATE TABLE IF NOT EXISTS `channels` (" +
|
||||
"`id` INT NOT NULL AUTO_INCREMENT," +
|
||||
"`name` VARCHAR(30) NOT NULL," +
|
||||
"`owner` VARCHAR(20) NOT NULL," +
|
||||
"`time` BIGINT NOT NULL," +
|
||||
"PRIMARY KEY (`id`), INDEX(`name`), INDEX(`owner`))" +
|
||||
"CHARACTER SET utf8");
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the given channel name is registered
|
||||
*/
|
||||
isChannelTaken: function (name, callback) {
|
||||
if (typeof callback !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
dbutil.query("SELECT name FROM `channels` WHERE name=?",
|
||||
[name],
|
||||
function (err, rows) {
|
||||
if (err) {
|
||||
callback(err, true);
|
||||
return;
|
||||
}
|
||||
callback(null, rows.length > 0);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Looks up a channel
|
||||
*/
|
||||
lookup: function (name, callback) {
|
||||
if (typeof callback !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
dbutil.query("SELECT * FROM `channels` WHERE name=?",
|
||||
[name],
|
||||
function (err, rows) {
|
||||
if (err) {
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
callback(null, rows);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches for a channel
|
||||
*/
|
||||
search: function (name, callback) {
|
||||
if (typeof callback !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
dbutil.query("SELECT * FROM `channels` WHERE name LIKE ?",
|
||||
["%" + name + "%"],
|
||||
function (err, rows) {
|
||||
if (err) {
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
callback(null, rows);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Validates and registers a new channel
|
||||
*/
|
||||
register: function (name, owner, callback) {
|
||||
if (typeof callback !== "function") {
|
||||
callback = blackHole;
|
||||
}
|
||||
|
||||
if (typeof name !== "string" || typeof owner !== "string") {
|
||||
callback("Name and owner are required for channel registration", null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$util.isValidChannelName(name)) {
|
||||
callback("Invalid channel name. Channel names may consist of 1-30 " +
|
||||
"characters a-z, A-Z, 0-9, -, and _", null);
|
||||
return;
|
||||
}
|
||||
|
||||
module.exports.isChannelTaken(name, function (err, taken) {
|
||||
if (err) {
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (taken) {
|
||||
callback("Channel name " + name + " is already taken", null);
|
||||
return;
|
||||
}
|
||||
|
||||
dbutil.query("INSERT INTO `channels` " +
|
||||
"(`name`, `owner`, `time`) VALUES (?, ?, ?)",
|
||||
[name, owner, Date.now()],
|
||||
function (err, res) {
|
||||
if (err) {
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
|
||||
initTables(name, owner, function (err, res) {
|
||||
if (err) {
|
||||
dbutil.query("DELETE FROM `channels` WHERE name=?", [name]);
|
||||
callback(err, null);
|
||||
return;
|
||||
}
|
||||
callback(null, {
|
||||
name: name
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Unregisters a channel
|
||||
*/
|
||||
drop: function (name, callback) {
|
||||
if (typeof callback !== "function") {
|
||||
callback = blackHole;
|
||||
}
|
||||
|
||||
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 + "_library", 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;
|
||||
}
|
||||
|
||||
callback(err, !Boolean(err));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Looks up channels registered by a given user
|
||||
*/
|
||||
listUserChannels: function (owner, callback) {
|
||||
if (typeof callback !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
db.query("SELECT * FROM `channels` WHERE owner=?", [owner],
|
||||
function (err, res) {
|
||||
if (err) {
|
||||
callback(err, []);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(err, res);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Looks up a user's rank
|
||||
*/
|
||||
getRank: function (chan, name, callback) {
|
||||
if (typeof callback !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
db.query("SELECT name,rank FROM `chan_" + chan + "_ranks` WHERE name=?",
|
||||
[name],
|
||||
function (err, rows) {
|
||||
if (err) {
|
||||
callback(err, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rows.length === 0) {
|
||||
callback(null, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, rows[0].rank);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Looks up multiple users' ranks at once
|
||||
*/
|
||||
getRanks: function (chan, names, callback) {
|
||||
if (typeof callback !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
var replace = "(" + names.map(function () { return "?"; }).join(",") + ")";
|
||||
db.query("SELECT name,rank FROM `chan_" + chan + "_ranks` WHERE name IN " +
|
||||
replace,
|
||||
function (err, rows) {
|
||||
if (err) {
|
||||
callback(err, []);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, rows);
|
||||
});
|
||||
},
|
||||
};
|
Loading…
Reference in a new issue