db/Pad.js: convert to promises/async

Also updated some small chunks of dependent code that couldn't be converted
until this one had been done.
pull/3559/head
Ray Bellis 2019-01-31 11:14:38 +00:00
parent ebb8a64e3c
commit 6d1b6b2796
4 changed files with 236 additions and 454 deletions

View File

@ -144,12 +144,11 @@ exports.getAuthor = function(author)
/** /**
* Returns the color Id of the author * Returns the color Id of the author
* @param {String} author The id of the author * @param {String} author The id of the author
* @param {Function} callback callback(err, colorId)
*/ */
exports.getAuthorColorId = thenify(function(author, callback) exports.getAuthorColorId = function(author)
{ {
db.db.getSub("globalAuthor:" + author, ["colorId"], callback); return db.getSub("globalAuthor:" + author, ["colorId"]);
}); }
/** /**
* Sets the color Id of the author * Sets the color Id of the author
@ -164,12 +163,11 @@ exports.setAuthorColorId = function(author, colorId)
/** /**
* Returns the name of the author * Returns the name of the author
* @param {String} author The id of the author * @param {String} author The id of the author
* @param {Function} callback callback(err, name)
*/ */
exports.getAuthorName = thenify(function(author, callback) exports.getAuthorName = function(author)
{ {
db.db.getSub("globalAuthor:" + author, ["name"], callback); return db.getSub("globalAuthor:" + author, ["name"]);
}); }
/** /**
* Sets the name of the author * Sets the name of the author

View File

@ -18,13 +18,11 @@
* limitations under the License. * limitations under the License.
*/ */
var ERR = require("async-stacktrace");
var customError = require("../utils/customError"); var customError = require("../utils/customError");
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString; var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
var db = require("./DB"); var db = require("./DB");
var padManager = require("./PadManager"); var padManager = require("./PadManager");
var sessionManager = require("./SessionManager"); var sessionManager = require("./SessionManager");
const thenify = require("thenify").withCallback;
exports.listAllGroups = async function() exports.listAllGroups = async function()
{ {
@ -85,15 +83,13 @@ exports.deleteGroup = async function(groupID)
await db.set("groups", newGroups); await db.set("groups", newGroups);
} }
// @TODO: this is the only function still called with a callback exports.doesGroupExist = async function(groupID)
exports.doesGroupExist = thenify(function(groupID, callback)
{ {
// try to get the group entry // try to get the group entry
db.db.get("group:" + groupID, function (err, group) { let group = await db.get("group:" + groupID);
if (ERR(err, callback)) return;
callback(null, group != null); return (group != null);
}); }
});
exports.createGroup = async function() exports.createGroup = async function()
{ {

View File

@ -3,11 +3,9 @@
*/ */
var ERR = require("async-stacktrace");
var Changeset = require("ep_etherpad-lite/static/js/Changeset"); var Changeset = require("ep_etherpad-lite/static/js/Changeset");
var AttributePool = require("ep_etherpad-lite/static/js/AttributePool"); var AttributePool = require("ep_etherpad-lite/static/js/AttributePool");
var db = require("./DB"); var db = require("./DB");
var async = require("async");
var settings = require('../utils/Settings'); var settings = require('../utils/Settings');
var authorManager = require("./AuthorManager"); var authorManager = require("./AuthorManager");
var padManager = require("./PadManager"); var padManager = require("./PadManager");
@ -18,8 +16,6 @@ var readOnlyManager = require("./ReadOnlyManager");
var crypto = require("crypto"); var crypto = require("crypto");
var randomString = require("../utils/randomstring"); var randomString = require("../utils/randomstring");
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
const thenify = require("thenify").withCallback;
const nodeify = require("nodeify");
// serialization/deserialization attributes // serialization/deserialization attributes
var attributeBlackList = ["id"]; var attributeBlackList = ["id"];
@ -34,7 +30,7 @@ exports.cleanText = function (txt) {
}; };
var Pad = function Pad(id) { let Pad = function Pad(id) {
this.atext = Changeset.makeAText("\n"); this.atext = Changeset.makeAText("\n");
this.pool = new AttributePool(); this.pool = new AttributePool();
this.head = -1; this.head = -1;
@ -129,7 +125,7 @@ Pad.prototype.saveToDatabase = function saveToDatabase() {
} }
} }
db.db.set("pad:" + this.id, dbObject); db.set("pad:" + this.id, dbObject);
} }
// get time of last edit (changeset application) // get time of last edit (changeset application)
@ -138,17 +134,17 @@ Pad.prototype.getLastEdit = function getLastEdit() {
return db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "timestamp"]); return db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "timestamp"]);
} }
Pad.prototype.getRevisionChangeset = thenify(function getRevisionChangeset(revNum, callback) { Pad.prototype.getRevisionChangeset = function getRevisionChangeset(revNum) {
db.db.getSub("pad:" + this.id + ":revs:" + revNum, ["changeset"], callback); return db.getSub("pad:" + this.id + ":revs:" + revNum, ["changeset"]);
}); }
Pad.prototype.getRevisionAuthor = thenify(function getRevisionAuthor(revNum, callback) { Pad.prototype.getRevisionAuthor = function getRevisionAuthor(revNum) {
db.db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "author"], callback); return db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "author"]);
}); }
Pad.prototype.getRevisionDate = thenify(function getRevisionDate(revNum, callback) { Pad.prototype.getRevisionDate = function getRevisionDate(revNum) {
db.db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "timestamp"], callback); return db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "timestamp"]);
}); }
Pad.prototype.getAllAuthors = function getAllAuthors() { Pad.prototype.getAllAuthors = function getAllAuthors() {
var authors = []; var authors = [];
@ -162,101 +158,57 @@ Pad.prototype.getAllAuthors = function getAllAuthors() {
return authors; return authors;
}; };
Pad.prototype.getInternalRevisionAText = thenify(function getInternalRevisionAText(targetRev, callback) { Pad.prototype.getInternalRevisionAText = async function getInternalRevisionAText(targetRev) {
var _this = this; let keyRev = this.getKeyRevisionNumber(targetRev);
var keyRev = this.getKeyRevisionNumber(targetRev);
var atext;
var changesets = [];
// find out which changesets are needed // find out which changesets are needed
var neededChangesets = []; let neededChangesets = [];
var curRev = keyRev; for (let curRev = keyRev; curRev < targetRev; ) {
while (curRev < targetRev) { neededChangesets.push(++curRev);
curRev++;
neededChangesets.push(curRev);
} }
async.series([ // get all needed data out of the database
// get all needed data out of the database
function(callback) {
async.parallel([
// get the atext of the key revision
function (callback) {
db.db.getSub("pad:" + _this.id + ":revs:" + keyRev, ["meta", "atext"], function(err, _atext) {
if (ERR(err, callback)) return;
try {
atext = Changeset.cloneAText(_atext);
} catch (e) {
return callback(e);
}
callback(); // get the atext of the key revision
}); let _atext = await db.getSub("pad:" + this.id + ":revs:" + keyRev, ["meta", "atext"]);
}, let atext = Changeset.cloneAText(_atext);
// get all needed changesets // get all needed changesets
function (callback) { let changesets = [];
async.forEach(neededChangesets, function(item, callback) { await Promise.all(neededChangesets.map(item => {
_this.getRevisionChangeset(item, function(err, changeset) { return this.getRevisionChangeset(item).then(changeset => {
if (ERR(err, callback)) return; changesets[item] = changeset;
changesets[item] = changeset; });
callback(); }));
});
}, callback);
}
], callback);
},
// apply all changesets to the key changeset // apply all changesets to the key changeset
function(callback) { let apool = this.apool();
var apool = _this.apool(); for (let curRev = keyRev; curRev < targetRev; ) {
var curRev = keyRev; let cs = changesets[++curRev];
atext = Changeset.applyToAText(cs, atext, apool);
}
while (curRev < targetRev) { return atext;
curRev++; }
var cs = changesets[curRev];
try {
atext = Changeset.applyToAText(cs, atext, apool);
} catch(e) {
return callback(e)
}
}
callback(null); Pad.prototype.getRevision = function getRevisionChangeset(revNum) {
} return db.get("pad:" + this.id + ":revs:" + revNum);
], }
function(err) {
if (ERR(err, callback)) return;
callback(null, atext);
});
});
Pad.prototype.getRevision = thenify(function getRevisionChangeset(revNum, callback) { Pad.prototype.getAllAuthorColors = async function getAllAuthorColors() {
db.db.get("pad:" + this.id + ":revs:" + revNum, callback); let authors = this.getAllAuthors();
}); let returnTable = {};
let colorPalette = authorManager.getColorPalette();
Pad.prototype.getAllAuthorColors = thenify(function getAllAuthorColors(callback) {
var authors = this.getAllAuthors();
var returnTable = {};
var colorPalette = authorManager.getColorPalette();
async.forEach(authors, function(author, callback) {
authorManager.getAuthorColorId(author, function(err, colorId) {
if (err) {
return callback(err);
}
await Promise.all(authors.map(author => {
return authorManager.getAuthorColorId(author).then(colorId => {
// colorId might be a hex color or an number out of the palette // colorId might be a hex color or an number out of the palette
returnTable[author] = colorPalette[colorId] || colorId; returnTable[author] = colorPalette[colorId] || colorId;
callback();
}); });
}, }));
function(err) {
callback(err, returnTable); return returnTable;
}); }
});
Pad.prototype.getValidRevisionRange = function getValidRevisionRange(startRev, endRev) { Pad.prototype.getValidRevisionRange = function getValidRevisionRange(startRev, endRev) {
startRev = parseInt(startRev, 10); startRev = parseInt(startRev, 10);
@ -327,83 +279,49 @@ Pad.prototype.appendChatMessage = function appendChatMessage(text, userId, time)
this.saveToDatabase(); this.saveToDatabase();
}; };
Pad.prototype.getChatMessage = thenify(function getChatMessage(entryNum, callback) { Pad.prototype.getChatMessage = async function getChatMessage(entryNum) {
var _this = this; // get the chat entry
var entry; let entry = await db.get("pad:" + this.id + ":chat:" + entryNum);
async.series([ // get the authorName if the entry exists
// get the chat entry if (entry != null) {
function(callback) { entry.userName = await authorManager.getAuthorName(entry.userId);
db.db.get("pad:" + _this.id + ":chat:" + entryNum, function(err, _entry) {
if (ERR(err, callback)) return;
entry = _entry;
callback();
});
},
// add the authorName
function(callback) {
// this chat message doesn't exist, return null
if (entry == null) {
callback();
return;
}
// get the authorName
authorManager.getAuthorName(entry.userId, function(err, authorName) {
if (ERR(err, callback)) return;
entry.userName = authorName;
callback();
});
}
],
function(err) {
if (ERR(err, callback)) return;
callback(null, entry);
});
});
Pad.prototype.getChatMessages = thenify(function getChatMessages(start, end, callback) {
// collect the numbers of chat entries and in which order we need them
var neededEntries = [];
var order = 0;
for (var i = start; i <= end; i++) {
neededEntries.push({ entryNum: i, order: order });
order++;
} }
var _this = this; return entry;
};
Pad.prototype.getChatMessages = async function getChatMessages(start, end) {
// collect the numbers of chat entries and in which order we need them
let neededEntries = [];
for (let order = 0, entryNum = start; entryNum <= end; ++order, ++entryNum) {
neededEntries.push({ entryNum, order });
}
// get all entries out of the database // get all entries out of the database
var entries = []; let entries = [];
async.forEach(neededEntries, function(entryObject, callback) { await Promise.all(neededEntries.map(entryObject => {
_this.getChatMessage(entryObject.entryNum, function(err, entry) { return this.getChatMessage(entryObject.entryNum).then(entry => {
if (ERR(err, callback)) return;
entries[entryObject.order] = entry; entries[entryObject.order] = entry;
callback();
}); });
}, }));
function(err) {
if (ERR(err, callback)) return;
// sort out broken chat entries // sort out broken chat entries
// it looks like in happened in the past that the chat head was // it looks like in happened in the past that the chat head was
// incremented, but the chat message wasn't added // incremented, but the chat message wasn't added
var cleanedEntries = []; let cleanedEntries = entries.filter(entry => {
for (var i=0; i < entries.length; i++) { let pass = (entry != null);
if (entries[i] != null) { if (!pass) {
cleanedEntries.push(entries[i]); console.warn("WARNING: Found broken chat entry in pad " + this.id);
} else {
console.warn("WARNING: Found broken chat entry in pad " + _this.id);
}
} }
return pass;
callback(null, cleanedEntries);
}); });
});
Pad.prototype.init = thenify(function init(text, callback) { return cleanedEntries;
var _this = this; }
Pad.prototype.init = async function init(text) {
// replace text with default text if text isn't set // replace text with default text if text isn't set
if (text == null) { if (text == null) {
@ -411,35 +329,31 @@ Pad.prototype.init = thenify(function init(text, callback) {
} }
// try to load the pad // try to load the pad
db.db.get("pad:" + this.id, function(err, value) { let value = await db.get("pad:" + this.id);
if (ERR(err, callback)) return;
// if this pad exists, load it // if this pad exists, load it
if (value != null) { if (value != null) {
// copy all attr. To a transfrom via fromJsonable if necessary // copy all attr. To a transfrom via fromJsonable if necassary
for (var attr in value) { for (var attr in value) {
if (jsonableList.indexOf(attr) !== -1) { if (jsonableList.indexOf(attr) !== -1) {
_this[attr] = _this[attr].fromJsonable(value[attr]); this[attr] = this[attr].fromJsonable(value[attr]);
} else { } else {
_this[attr] = value[attr]; this[attr] = value[attr];
}
} }
} else {
// this pad doesn't exist, so create it
var firstChangeset = Changeset.makeSplice("\n", 0, 0, exports.cleanText(text));
_this.appendRevision(firstChangeset, '');
} }
} else {
// this pad doesn't exist, so create it
let firstChangeset = Changeset.makeSplice("\n", 0, 0, exports.cleanText(text));
hooks.callAll("padLoad", { 'pad': _this }); this.appendRevision(firstChangeset, '');
callback(null); }
});
});
Pad.prototype.copy = thenify(function copy(destinationID, force, callback) { hooks.callAll("padLoad", { 'pad': this });
var sourceID = this.id; }
var _this = this;
var destGroupID; Pad.prototype.copy = async function copy(destinationID, force) {
let sourceID = this.id;
// allow force to be a string // allow force to be a string
if (typeof force === "string") { if (typeof force === "string") {
@ -454,236 +368,134 @@ Pad.prototype.copy = thenify(function copy(destinationID, force, callback) {
// padMessageHandler.kickSessionsFromPad(sourceID); // padMessageHandler.kickSessionsFromPad(sourceID);
// flush the source pad: // flush the source pad:
_this.saveToDatabase(); this.saveToDatabase();
async.series([ // if it's a group pad, let's make sure the group exists.
// if it's a group pad, let's make sure the group exists. let destGroupID;
function(callback) { if (destinationID.indexOf("$") >= 0) {
if (destinationID.indexOf("$") === -1) {
callback();
return;
}
destGroupID = destinationID.split("$")[0]; destGroupID = destinationID.split("$")[0]
groupManager.doesGroupExist(destGroupID, function (err, exists) { let groupExists = await groupManager.doesGroupExist(destGroupID);
if (ERR(err, callback)) return;
// group does not exist // group does not exist
if (exists == false) { if (!groupExists) {
callback(new customError("groupID does not exist for destinationID", "apierror")); throw new customError("groupID does not exist for destinationID", "apierror");
return;
}
// everything is fine, continue
callback();
});
},
// if the pad exists, we should abort, unless forced.
function(callback) {
padManager.doesPadExists(destinationID, function (err, exists) {
if (ERR(err, callback)) return;
/*
* this is the negation of a truthy comparison. Has been left in this
* wonky state to keep the old (possibly buggy) behaviour
*/
if (!(exists == true)) {
callback();
return;
}
if (!force) {
console.error("erroring out without force");
callback(new customError("destinationID already exists", "apierror"));
console.error("erroring out without force - after");
return;
}
// exists and forcing
padManager.getPad(destinationID, function(err, pad) {
if (ERR(err, callback)) return;
pad.remove(callback);
});
});
},
// copy the 'pad' entry
function(callback) {
db.db.get("pad:" + sourceID, function(err, pad) {
db.set("pad:" + destinationID, pad);
});
callback();
},
// copy all relations
function(callback) {
async.parallel([
// copy all chat messages
function(callback) {
var chatHead = _this.chatHead;
for (var i=0; i <= chatHead; i++) {
db.db.get("pad:" + sourceID + ":chat:" + i, function (err, chat) {
if (ERR(err, callback)) return;
db.set("pad:" + destinationID + ":chat:" + i, chat);
});
}
callback();
},
// copy all revisions
function(callback) {
var revHead = _this.head;
for (var i=0; i <= revHead; i++) {
db.db.get("pad:" + sourceID + ":revs:" + i, function (err, rev) {
if (ERR(err, callback)) return;
db.set("pad:" + destinationID + ":revs:" + i, rev);
});
}
callback();
},
// add the new pad to all authors who contributed to the old one
function(callback) {
var authorIDs = _this.getAllAuthors();
authorIDs.forEach(function (authorID) {
authorManager.addPad(authorID, destinationID);
});
callback();
},
// parallel
], callback);
},
function(callback) {
if (destGroupID) {
// Group pad? Add it to the group's list
db.setSub("group:" + destGroupID, ["pads", destinationID], 1);
}
// Initialize the new pad (will update the listAllPads cache)
setTimeout(function() {
padManager.getPad(destinationID, null, callback) // this runs too early.
}, 10);
},
// let the plugins know the pad was copied
function(callback) {
hooks.callAll('padCopy', { 'originalPad': _this, 'destinationID': destinationID });
callback();
} }
// series }
],
function(err) {
if (ERR(err, callback)) return;
callback(null, { padID: destinationID });
});
});
Pad.prototype.remove = thenify(function remove(callback) { // if the pad exists, we should abort, unless forced.
let exists = await padManager.doesPadExist(destinationID);
if (exists) {
if (!force) {
console.error("erroring out without force");
throw new customError("destinationID already exists", "apierror");
return;
}
// exists and forcing
let pad = await padManager.getPad(destinationID);
await pad.remove(callback);
}
// copy the 'pad' entry
let pad = await db.get("pad:" + sourceID);
db.set("pad:" + destinationID, pad);
// copy all relations in parallel
let promises = [];
// copy all chat messages
let chatHead = this.chatHead;
for (let i = 0; i <= chatHead; ++i) {
let p = db.get("pad:" + sourceID + ":chat:" + i).then(chat => {
return db.set("pad:" + destinationID + ":chat:" + i, chat);
});
promises.push(p);
}
// copy all revisions
let revHead = this.head;
for (let i = 0; i <= revHead; ++i) {
let p = db.get("pad:" + sourceID + ":revs:" + i).then(rev => {
return db.set("pad:" + destinationID + ":revs:" + i, rev);
});
promises.push(p);
}
// add the new pad to all authors who contributed to the old one
this.getAllAuthors().forEach(authorID => {
authorManager.addPad(authorID, destinationID);
});
// wait for the above to complete
await Promise.all(promises);
// Group pad? Add it to the group's list
if (destGroupID) {
await db.setSub("group:" + destGroupID, ["pads", destinationID], 1);
}
// delay still necessary?
await new Promise(resolve => setTimeout(resolve, 10));
// Initialize the new pad (will update the listAllPads cache)
await padManager.getPad(destinationID, null); // this runs too early.
// let the plugins know the pad was copied
hooks.callAll('padCopy', { 'originalPad': this, 'destinationID': destinationID });
return { padID: destinationID };
}
Pad.prototype.remove = async function remove() {
var padID = this.id; var padID = this.id;
var _this = this;
// kick everyone from this pad // kick everyone from this pad
padMessageHandler.kickSessionsFromPad(padID); padMessageHandler.kickSessionsFromPad(padID);
async.series([ // delete all relations
// delete all relations
function(callback) { // is it a group pad? -> delete the entry of this pad in the group
async.parallel([ if (padID.indexOf("$") >= 0) {
// is it a group pad? -> delete the entry of this pad in the group
function(callback) {
if (padID.indexOf("$") === -1) {
// it isn't a group pad, nothing to do here
callback();
return;
}
// it is a group pad // it is a group pad
var groupID = padID.substring(0, padID.indexOf("$")); let groupID = padID.substring(0, padID.indexOf("$"));
let group = await db.get("group:" + groupID);
db.db.get("group:" + groupID, function (err, group) { // remove the pad entry
if (ERR(err, callback)) return; delete group.pads[padID];
// remove the pad entry // set the new value
delete group.pads[padID]; db.set("group:" + groupID, group);
}
// set the new value // remove the readonly entries
db.set("group:" + groupID, group); let readonlyID = readOnlyManager.getReadOnlyId(padID);
callback(); db.remove("pad2readonly:" + padID);
}); db.remove("readonly2pad:" + readonlyID);
},
// remove the readonly entries // delete all chat messages
function(callback) { for (let i = 0, n = this.chatHead; i <= n; ++i) {
// @TODO - temporary until surrounding code is Promisified db.remove("pad:" + padID + ":chat:" + i);
function getReadOnlyId(padID, callback) { }
return nodeify(readOnlyManager.getReadOnlyId(padID), callback);
}
getReadOnlyId(padID, function(err, readonlyID) { // delete all revisions
if (ERR(err, callback)) return; for (let i = 0, n = this.head; i <= n; ++i) {
db.remove("pad:" + padID + ":revs:" + i);
}
db.remove("pad2readonly:" + padID); // remove pad from all authors who contributed
db.remove("readonly2pad:" + readonlyID); this.getAllAuthors().forEach(authorID => {
authorManager.removePad(authorID, padID);
callback();
});
},
// delete all chat messages
function(callback) {
var chatHead = _this.chatHead;
for (var i = 0; i <= chatHead; i++) {
db.remove("pad:" + padID + ":chat:" + i);
}
callback();
},
// delete all revisions
function(callback) {
var revHead = _this.head;
for (var i = 0; i <= revHead; i++) {
db.remove("pad:" + padID + ":revs:" + i);
}
callback();
},
// remove pad from all authors who contributed
function(callback) {
var authorIDs = _this.getAllAuthors();
authorIDs.forEach(function (authorID) {
authorManager.removePad(authorID, padID);
});
callback();
}
], callback);
},
// delete the pad entry and delete pad from padManager
function(callback) {
padManager.removePad(padID);
hooks.callAll("padRemove", { 'padID': padID });
callback();
}
],
function(err) {
if (ERR(err, callback)) return;
callback();
}); });
});
// delete the pad entry and delete pad from padManager
padManager.removePad(padID);
hooks.callAll("padRemove", { padID });
}
// set in db // set in db
Pad.prototype.setPublicStatus = function setPublicStatus(publicStatus) { Pad.prototype.setPublicStatus = function setPublicStatus(publicStatus) {

View File

@ -18,11 +18,9 @@
* limitations under the License. * limitations under the License.
*/ */
var ERR = require("async-stacktrace");
var customError = require("../utils/customError"); var customError = require("../utils/customError");
var Pad = require("../db/Pad").Pad; var Pad = require("../db/Pad").Pad;
var db = require("./DB").db; var db = require("./DB");
const thenify = require("thenify").withCallback;
/** /**
* A cache of all loaded Pads. * A cache of all loaded Pads.
@ -114,59 +112,43 @@ let padList = {
* @param id A String with the id of the pad * @param id A String with the id of the pad
* @param {Function} callback * @param {Function} callback
*/ */
exports.getPad = thenify(function(id, text, callback) exports.getPad = async function(id, text)
{ {
// check if this is a valid padId // check if this is a valid padId
if (!exports.isValidPadId(id)) { if (!exports.isValidPadId(id)) {
callback(new customError(id + " is not a valid padId", "apierror")); throw new customError(id + " is not a valid padId", "apierror");
return;
}
// make text an optional parameter
if (typeof text == "function") {
callback = text;
text = null;
} }
// check if this is a valid text // check if this is a valid text
if (text != null) { if (text != null) {
// check if text is a string // check if text is a string
if (typeof text != "string") { if (typeof text != "string") {
callback(new customError("text is not a string", "apierror")); throw new customError("text is not a string", "apierror");
return;
} }
// check if text is less than 100k chars // check if text is less than 100k chars
if (text.length > 100000) { if (text.length > 100000) {
callback(new customError("text must be less than 100k chars", "apierror")); throw new customError("text must be less than 100k chars", "apierror");
return;
} }
} }
var pad = globalPads.get(id); let pad = globalPads.get(id);
// return pad if it's already loaded // return pad if it's already loaded
if (pad != null) { if (pad != null) {
callback(null, pad); return pad;
return;
} }
// try to load pad // try to load pad
pad = new Pad(id); pad = new Pad(id);
// initalize the pad // initalize the pad
pad.init(text, function(err) { await pad.init(text);
if (ERR(err, callback)) return; globalPads.set(id, pad);
padList.addPad(id);
globalPads.set(id, pad); return pad;
padList.addPad(id); }
callback(null, pad);
});
});
exports.listAllPads = async function() exports.listAllPads = async function()
{ {
@ -176,18 +158,12 @@ exports.listAllPads = async function()
} }
// checks if a pad exists // checks if a pad exists
exports.doesPadExist = thenify(function(padId, callback) exports.doesPadExist = async function(padId)
{ {
db.get("pad:" + padId, function(err, value) { let value = await db.get("pad:" + padId);
if (ERR(err, callback)) return;
if (value != null && value.atext) { return (value != null && value.atext);
callback(null, true); }
} else {
callback(null, false);
}
});
});
// alias for backwards compatibility // alias for backwards compatibility
exports.doesPadExists = exports.doesPadExist; exports.doesPadExists = exports.doesPadExist;