bin/rebuildPad.js: Asyncify

pull/4656/head
Richard Hansen 2021-01-29 17:01:04 -05:00 committed by John McLear
parent 72c2abab8d
commit 5b519b9a9c
1 changed files with 68 additions and 92 deletions

View File

@ -13,7 +13,6 @@ if (process.argv.length !== 4 && process.argv.length !== 5) {
throw new Error('Use: node bin/repairPad.js $PADID $REV [$NEWPADID]'); throw new Error('Use: node bin/repairPad.js $PADID $REV [$NEWPADID]');
} }
const async = require('ep_etherpad-lite/node_modules/async');
const npm = require('ep_etherpad-lite/node_modules/npm'); const npm = require('ep_etherpad-lite/node_modules/npm');
const util = require('util'); const util = require('util');
@ -21,19 +20,14 @@ const padId = process.argv[2];
const newRevHead = process.argv[3]; const newRevHead = process.argv[3];
const newPadId = process.argv[4] || `${padId}-rebuilt`; const newPadId = process.argv[4] || `${padId}-rebuilt`;
let db, oldPad, newPad; (async () => {
let Pad, PadManager; await util.promisify(npm.load)({});
async.series([ const db = require('ep_etherpad-lite/node/db/DB');
(callback) => npm.load({}, callback), await db.init();
(callback) => {
// Get a handle into the database const Pad = require('ep_etherpad-lite/node/db/Pad').Pad;
db = require('ep_etherpad-lite/node/db/DB'); const PadManager = require('ep_etherpad-lite/node/db/PadManager');
util.callbackify(db.init)(callback);
},
(callback) => {
Pad = require('ep_etherpad-lite/node/db/Pad').Pad;
PadManager = require('ep_etherpad-lite/node/db/PadManager');
// Get references to the original pad and to a newly created pad // Get references to the original pad and to a newly created pad
// HACK: This is a standalone script, so we want to write everything // HACK: This is a standalone script, so we want to write everything
// out to the database immediately. The only problem with this is // out to the database immediately. The only problem with this is
@ -44,32 +38,20 @@ async.series([
if (!PadManager.isValidPadId(newPadId)) { if (!PadManager.isValidPadId(newPadId)) {
throw new Error('Cannot create a pad with that id as it is invalid'); throw new Error('Cannot create a pad with that id as it is invalid');
} }
util.callbackify(PadManager.doesPadExist)(newPadId, (err, exists) => { const exists = await PadManager.doesPadExist(newPadId);
if (err != null) return callback(err);
if (exists) throw new Error('Cannot create a pad with that id as it already exists'); if (exists) throw new Error('Cannot create a pad with that id as it already exists');
callback();
}); const oldPad = await PadManager.getPad(padId);
}, const newPad = new Pad(newPadId);
(callback) => {
util.callbackify(PadManager.getPad)(padId, (err, pad) => {
if (err) return callback(err);
oldPad = pad;
newPad = new Pad(newPadId);
callback();
});
},
(callback) => {
// Clone all Chat revisions // Clone all Chat revisions
const chatHead = oldPad.chatHead; const chatHead = oldPad.chatHead;
for (let i = 0, curHeadNum = 0; i <= chatHead; i++) { await Promise.all([...Array(chatHead + 1).keys()].map(async (i) => {
db.db.get(`pad:${padId}:chat:${i}`, (err, chat) => { const chat = await db.get(`pad:${padId}:chat:${i}`);
db.db.set(`pad:${newPadId}:chat:${curHeadNum++}`, chat); await db.set(`pad:${newPadId}:chat:${i}`, chat);
console.log(`Created: Chat Revision: pad:${newPadId}:chat:${curHeadNum}`); console.log(`Created: Chat Revision: pad:${newPadId}:chat:${i}`);
}); }));
}
callback();
},
(callback) => {
// Rebuild Pad from revisions up to and including the new revision head // Rebuild Pad from revisions up to and including the new revision head
const AuthorManager = require('ep_etherpad-lite/node/db/AuthorManager'); const AuthorManager = require('ep_etherpad-lite/node/db/AuthorManager');
const Changeset = require('ep_etherpad-lite/static/js/Changeset'); const Changeset = require('ep_etherpad-lite/static/js/Changeset');
@ -78,23 +60,20 @@ async.series([
// and, AFAICT, cannot be recreated any other way // and, AFAICT, cannot be recreated any other way
newPad.pool.numToAttrib = oldPad.pool.numToAttrib; newPad.pool.numToAttrib = oldPad.pool.numToAttrib;
for (let curRevNum = 0; curRevNum <= newRevHead; curRevNum++) { for (let curRevNum = 0; curRevNum <= newRevHead; curRevNum++) {
db.db.get(`pad:${padId}:revs:${curRevNum}`, (err, rev) => { const rev = await db.get(`pad:${padId}:revs:${curRevNum}`);
if (rev.meta) { if (rev.meta) {
throw new Error('The specified revision number could not be found.'); throw new Error('The specified revision number could not be found.');
} }
const newRevNum = ++newPad.head; const newRevNum = ++newPad.head;
const newRevId = `pad:${newPad.id}:revs:${newRevNum}`; const newRevId = `pad:${newPad.id}:revs:${newRevNum}`;
db.db.set(newRevId, rev); await Promise.all([
AuthorManager.addPad(rev.meta.author, newPad.id); db.set(newRevId, rev),
AuthorManager.addPad(rev.meta.author, newPad.id),
]);
newPad.atext = Changeset.applyToAText(rev.changeset, newPad.atext, newPad.pool); newPad.atext = Changeset.applyToAText(rev.changeset, newPad.atext, newPad.pool);
console.log(`Created: Revision: pad:${newPad.id}:revs:${newRevNum}`); console.log(`Created: Revision: pad:${newPad.id}:revs:${newRevNum}`);
if (newRevNum === newRevHead) {
callback();
} }
});
}
},
(callback) => {
// Add saved revisions up to the new revision head // Add saved revisions up to the new revision head
console.log(newPad.head); console.log(newPad.head);
const newSavedRevisions = []; const newSavedRevisions = [];
@ -105,15 +84,12 @@ async.series([
} }
} }
newPad.savedRevisions = newSavedRevisions; newPad.savedRevisions = newSavedRevisions;
callback();
},
// Save the source pad // Save the source pad
(callback) => db.db.set(`pad:${newPadId}`, newPad, callback), await db.set(`pad:${newPadId}`, newPad);
(callback) => {
console.log(`Created: Source Pad: pad:${newPadId}`); console.log(`Created: Source Pad: pad:${newPadId}`);
util.callbackify(newPad.saveToDatabase.bind(newPad))(callback); await newPad.saveToDatabase();
},
], (err) => {
if (err) throw err;
console.info('finished'); console.info('finished');
}); })();