MongoManager.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* eslint-disable
  2. camelcase,
  3. handle-callback-err,
  4. no-unused-vars,
  5. */
  6. // TODO: This file was created by bulk-decaffeinate.
  7. // Fix any style issues and re-enable lint.
  8. /*
  9. * decaffeinate suggestions:
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * DS207: Consider shorter variations of null checks
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. let MongoManager;
  15. const {db, ObjectId} = require("./mongojs");
  16. const PackManager = require("./PackManager");
  17. const async = require("async");
  18. const _ = require("underscore");
  19. const metrics = require('metrics-sharelatex');
  20. const logger = require('logger-sharelatex');
  21. module.exports = (MongoManager = {
  22. getLastCompressedUpdate(doc_id, callback) {
  23. if (callback == null) { callback = function(error, update) {}; }
  24. return db.docHistory
  25. .find({doc_id: ObjectId(doc_id.toString())}, {pack: {$slice:-1}}) // only return the last entry in a pack
  26. .sort({ v: -1 })
  27. .limit(1)
  28. .toArray(function(error, compressedUpdates) {
  29. if (error != null) { return callback(error); }
  30. return callback(null, compressedUpdates[0] || null);
  31. });
  32. },
  33. peekLastCompressedUpdate(doc_id, callback) {
  34. // under normal use we pass back the last update as
  35. // callback(null,update,version).
  36. //
  37. // when we have an existing last update but want to force a new one
  38. // to start, we pass it back as callback(null,null,version), just
  39. // giving the version so we can check consistency.
  40. if (callback == null) { callback = function(error, update, version) {}; }
  41. return MongoManager.getLastCompressedUpdate(doc_id, function(error, update) {
  42. if (error != null) { return callback(error); }
  43. if (update != null) {
  44. if (update.broken) { // marked as broken so we will force a new op
  45. return callback(null, null);
  46. } else if (update.pack != null) {
  47. if (update.finalised) { // no more ops can be appended
  48. return callback(null, null, update.pack[0] != null ? update.pack[0].v : undefined);
  49. } else {
  50. return callback(null, update, update.pack[0] != null ? update.pack[0].v : undefined);
  51. }
  52. } else {
  53. return callback(null, update, update.v);
  54. }
  55. } else {
  56. return PackManager.getLastPackFromIndex(doc_id, function(error, pack) {
  57. if (error != null) { return callback(error); }
  58. if (((pack != null ? pack.inS3 : undefined) != null) && ((pack != null ? pack.v_end : undefined) != null)) { return callback(null, null, pack.v_end); }
  59. return callback(null, null);
  60. });
  61. }
  62. });
  63. },
  64. backportProjectId(project_id, doc_id, callback) {
  65. if (callback == null) { callback = function(error) {}; }
  66. return db.docHistory.update({
  67. doc_id: ObjectId(doc_id.toString()),
  68. project_id: { $exists: false }
  69. }, {
  70. $set: { project_id: ObjectId(project_id.toString()) }
  71. }, {
  72. multi: true
  73. }, callback);
  74. },
  75. getProjectMetaData(project_id, callback) {
  76. if (callback == null) { callback = function(error, metadata) {}; }
  77. return db.projectHistoryMetaData.find({
  78. project_id: ObjectId(project_id.toString())
  79. }, function(error, results) {
  80. if (error != null) { return callback(error); }
  81. return callback(null, results[0]);
  82. });
  83. },
  84. setProjectMetaData(project_id, metadata, callback) {
  85. if (callback == null) { callback = function(error) {}; }
  86. return db.projectHistoryMetaData.update({
  87. project_id: ObjectId(project_id)
  88. }, {
  89. $set: metadata
  90. }, {
  91. upsert: true
  92. }, callback);
  93. },
  94. upgradeHistory(project_id, callback) {
  95. // preserve the project's existing history
  96. if (callback == null) { callback = function(error) {}; }
  97. return db.docHistory.update({
  98. project_id: ObjectId(project_id),
  99. temporary: true,
  100. expiresAt: {$exists: true}
  101. }, {
  102. $set: {temporary: false},
  103. $unset: {expiresAt: ""}
  104. }, {
  105. multi: true
  106. }, callback);
  107. },
  108. ensureIndices() {
  109. // For finding all updates that go into a diff for a doc
  110. db.docHistory.ensureIndex({ doc_id: 1, v: 1 }, { background: true });
  111. // For finding all updates that affect a project
  112. db.docHistory.ensureIndex({ project_id: 1, "meta.end_ts": 1 }, { background: true });
  113. // For finding updates that don't yet have a project_id and need it inserting
  114. db.docHistory.ensureIndex({ doc_id: 1, project_id: 1 }, { background: true });
  115. // For finding project meta-data
  116. db.projectHistoryMetaData.ensureIndex({ project_id: 1 }, { background: true });
  117. // TTL index for auto deleting week old temporary ops
  118. db.docHistory.ensureIndex({ expiresAt: 1 }, { expireAfterSeconds: 0, background: true });
  119. // For finding packs to be checked for archiving
  120. db.docHistory.ensureIndex({ last_checked: 1 }, { background: true });
  121. // For finding archived packs
  122. return db.docHistoryIndex.ensureIndex({ project_id: 1 }, { background: true });
  123. }
  124. });
  125. [
  126. 'getLastCompressedUpdate',
  127. 'getProjectMetaData',
  128. 'setProjectMetaData'
  129. ].map(method => metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger));