MongoManager.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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) {
  24. callback = function(error, update) {}
  25. }
  26. return db.docHistory
  27. .find({ doc_id: ObjectId(doc_id.toString()) }, { pack: { $slice: -1 } }) // only return the last entry in a pack
  28. .sort({ v: -1 })
  29. .limit(1)
  30. .toArray(function(error, compressedUpdates) {
  31. if (error != null) {
  32. return callback(error)
  33. }
  34. return callback(null, compressedUpdates[0] || null)
  35. })
  36. },
  37. peekLastCompressedUpdate(doc_id, callback) {
  38. // under normal use we pass back the last update as
  39. // callback(null,update,version).
  40. //
  41. // when we have an existing last update but want to force a new one
  42. // to start, we pass it back as callback(null,null,version), just
  43. // giving the version so we can check consistency.
  44. if (callback == null) {
  45. callback = function(error, update, version) {}
  46. }
  47. return MongoManager.getLastCompressedUpdate(doc_id, function(
  48. error,
  49. update
  50. ) {
  51. if (error != null) {
  52. return callback(error)
  53. }
  54. if (update != null) {
  55. if (update.broken) {
  56. // marked as broken so we will force a new op
  57. return callback(null, null)
  58. } else if (update.pack != null) {
  59. if (update.finalised) {
  60. // no more ops can be appended
  61. return callback(
  62. null,
  63. null,
  64. update.pack[0] != null ? update.pack[0].v : undefined
  65. )
  66. } else {
  67. return callback(
  68. null,
  69. update,
  70. update.pack[0] != null ? update.pack[0].v : undefined
  71. )
  72. }
  73. } else {
  74. return callback(null, update, update.v)
  75. }
  76. } else {
  77. return PackManager.getLastPackFromIndex(doc_id, function(error, pack) {
  78. if (error != null) {
  79. return callback(error)
  80. }
  81. if (
  82. (pack != null ? pack.inS3 : undefined) != null &&
  83. (pack != null ? pack.v_end : undefined) != null
  84. ) {
  85. return callback(null, null, pack.v_end)
  86. }
  87. return callback(null, null)
  88. })
  89. }
  90. })
  91. },
  92. backportProjectId(project_id, doc_id, callback) {
  93. if (callback == null) {
  94. callback = function(error) {}
  95. }
  96. return db.docHistory.update(
  97. {
  98. doc_id: ObjectId(doc_id.toString()),
  99. project_id: { $exists: false }
  100. },
  101. {
  102. $set: { project_id: ObjectId(project_id.toString()) }
  103. },
  104. {
  105. multi: true
  106. },
  107. callback
  108. )
  109. },
  110. getProjectMetaData(project_id, callback) {
  111. if (callback == null) {
  112. callback = function(error, metadata) {}
  113. }
  114. return db.projectHistoryMetaData.find(
  115. {
  116. project_id: ObjectId(project_id.toString())
  117. },
  118. function(error, results) {
  119. if (error != null) {
  120. return callback(error)
  121. }
  122. return callback(null, results[0])
  123. }
  124. )
  125. },
  126. setProjectMetaData(project_id, metadata, callback) {
  127. if (callback == null) {
  128. callback = function(error) {}
  129. }
  130. return db.projectHistoryMetaData.update(
  131. {
  132. project_id: ObjectId(project_id)
  133. },
  134. {
  135. $set: metadata
  136. },
  137. {
  138. upsert: true
  139. },
  140. callback
  141. )
  142. },
  143. upgradeHistory(project_id, callback) {
  144. // preserve the project's existing history
  145. if (callback == null) {
  146. callback = function(error) {}
  147. }
  148. return db.docHistory.update(
  149. {
  150. project_id: ObjectId(project_id),
  151. temporary: true,
  152. expiresAt: { $exists: true }
  153. },
  154. {
  155. $set: { temporary: false },
  156. $unset: { expiresAt: '' }
  157. },
  158. {
  159. multi: true
  160. },
  161. callback
  162. )
  163. },
  164. ensureIndices() {
  165. // For finding all updates that go into a diff for a doc
  166. db.docHistory.ensureIndex({ doc_id: 1, v: 1 }, { background: true })
  167. // For finding all updates that affect a project
  168. db.docHistory.ensureIndex(
  169. { project_id: 1, 'meta.end_ts': 1 },
  170. { background: true }
  171. )
  172. // For finding updates that don't yet have a project_id and need it inserting
  173. db.docHistory.ensureIndex(
  174. { doc_id: 1, project_id: 1 },
  175. { background: true }
  176. )
  177. // For finding project meta-data
  178. db.projectHistoryMetaData.ensureIndex(
  179. { project_id: 1 },
  180. { background: true }
  181. )
  182. // TTL index for auto deleting week old temporary ops
  183. db.docHistory.ensureIndex(
  184. { expiresAt: 1 },
  185. { expireAfterSeconds: 0, background: true }
  186. )
  187. // For finding packs to be checked for archiving
  188. db.docHistory.ensureIndex({ last_checked: 1 }, { background: true })
  189. // For finding archived packs
  190. return db.docHistoryIndex.ensureIndex(
  191. { project_id: 1 },
  192. { background: true }
  193. )
  194. }
  195. }
  196. ;[
  197. 'getLastCompressedUpdate',
  198. 'getProjectMetaData',
  199. 'setProjectMetaData'
  200. ].map(method =>
  201. metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger)
  202. )