You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.8 KiB

4 years ago
  1. /*
  2. * This is a debug tool. It checks all revisions for data corruption
  3. */
  4. if (process.argv.length != 2) {
  5. console.error('Use: node bin/checkAllPads.js');
  6. process.exit(1);
  7. }
  8. // load and initialize NPM
  9. const npm = require('../src/node_modules/npm');
  10. npm.load({}, async () => {
  11. try {
  12. // initialize the database
  13. const settings = require('../src/node/utils/Settings');
  14. const db = require('../src/node/db/DB');
  15. await db.init();
  16. // load modules
  17. const Changeset = require('../src/static/js/Changeset');
  18. const padManager = require('../src/node/db/PadManager');
  19. // get all pads
  20. const res = await padManager.listAllPads();
  21. for (const padId of res.padIDs) {
  22. const pad = await padManager.getPad(padId);
  23. // check if the pad has a pool
  24. if (pad.pool === undefined) {
  25. console.error(`[${pad.id}] Missing attribute pool`);
  26. continue;
  27. }
  28. // create an array with key kevisions
  29. // key revisions always save the full pad atext
  30. const head = pad.getHeadRevisionNumber();
  31. const keyRevisions = [];
  32. for (let rev = 0; rev < head; rev += 100) {
  33. keyRevisions.push(rev);
  34. }
  35. // run through all key revisions
  36. for (const keyRev of keyRevisions) {
  37. // create an array of revisions we need till the next keyRevision or the End
  38. const revisionsNeeded = [];
  39. for (let rev = keyRev; rev <= keyRev + 100 && rev <= head; rev++) {
  40. revisionsNeeded.push(rev);
  41. }
  42. // this array will hold all revision changesets
  43. const revisions = [];
  44. // run through all needed revisions and get them from the database
  45. for (const revNum of revisionsNeeded) {
  46. const revision = await db.get(`pad:${pad.id}:revs:${revNum}`);
  47. revisions[revNum] = revision;
  48. }
  49. // check if the revision exists
  50. if (revisions[keyRev] == null) {
  51. console.error(`[${pad.id}] Missing revision ${keyRev}`);
  52. continue;
  53. }
  54. // check if there is a atext in the keyRevisions
  55. if (revisions[keyRev].meta === undefined || revisions[keyRev].meta.atext === undefined) {
  56. console.error(`[${pad.id}] Missing atext in revision ${keyRev}`);
  57. continue;
  58. }
  59. const apool = pad.pool;
  60. let atext = revisions[keyRev].meta.atext;
  61. for (let rev = keyRev + 1; rev <= keyRev + 100 && rev <= head; rev++) {
  62. try {
  63. const cs = revisions[rev].changeset;
  64. atext = Changeset.applyToAText(cs, atext, apool);
  65. } catch (e) {
  66. console.error(`[${pad.id}] Bad changeset at revision ${i} - ${e.message}`);
  67. }
  68. }
  69. }
  70. console.log('finished');
  71. process.exit(0);
  72. }
  73. } catch (err) {
  74. console.trace(err);
  75. process.exit(1);
  76. }
  77. });