MongoManager.coffee 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. {db, ObjectId} = require "./mongojs"
  2. PackManager = require "./PackManager"
  3. async = require "async"
  4. _ = require "underscore"
  5. metrics = require 'metrics-sharelatex'
  6. logger = require 'logger-sharelatex'
  7. module.exports = MongoManager =
  8. getLastCompressedUpdate: (doc_id, callback = (error, update) ->) ->
  9. db.docHistory
  10. .find(doc_id: ObjectId(doc_id.toString()), {pack: {$slice:-1}}) # only return the last entry in a pack
  11. .sort( v: -1 )
  12. .limit(1)
  13. .toArray (error, compressedUpdates) ->
  14. return callback(error) if error?
  15. callback null, compressedUpdates[0] or null
  16. peekLastCompressedUpdate: (doc_id, callback = (error, update, version) ->) ->
  17. # under normal use we pass back the last update as
  18. # callback(null,update,version).
  19. #
  20. # when we have an existing last update but want to force a new one
  21. # to start, we pass it back as callback(null,null,version), just
  22. # giving the version so we can check consistency.
  23. MongoManager.getLastCompressedUpdate doc_id, (error, update) ->
  24. return callback(error) if error?
  25. if update?
  26. if update.broken # marked as broken so we will force a new op
  27. return callback null, null
  28. else if update.pack?
  29. if update.finalised # no more ops can be appended
  30. return callback null, null, update.pack[0]?.v
  31. else
  32. return callback null, update, update.pack[0]?.v
  33. else
  34. return callback null, update, update.v
  35. else
  36. PackManager.getLastPackFromIndex doc_id, (error, pack) ->
  37. return callback(error) if error?
  38. return callback(null, null, pack.v_end) if pack?.inS3? and pack?.v_end?
  39. callback null, null
  40. backportProjectId: (project_id, doc_id, callback = (error) ->) ->
  41. db.docHistory.update {
  42. doc_id: ObjectId(doc_id.toString())
  43. project_id: { $exists: false }
  44. }, {
  45. $set: { project_id: ObjectId(project_id.toString()) }
  46. }, {
  47. multi: true
  48. }, callback
  49. getProjectMetaData: (project_id, callback = (error, metadata) ->) ->
  50. db.projectHistoryMetaData.find {
  51. project_id: ObjectId(project_id.toString())
  52. }, (error, results) ->
  53. return callback(error) if error?
  54. callback null, results[0]
  55. setProjectMetaData: (project_id, metadata, callback = (error) ->) ->
  56. db.projectHistoryMetaData.update {
  57. project_id: ObjectId(project_id)
  58. }, {
  59. $set: metadata
  60. }, {
  61. upsert: true
  62. }, callback
  63. upgradeHistory: (project_id, callback = (error) ->) ->
  64. # preserve the project's existing history
  65. db.docHistory.update {
  66. project_id: ObjectId(project_id)
  67. temporary: true
  68. expiresAt: {$exists: true}
  69. }, {
  70. $set: {temporary: false}
  71. $unset: {expiresAt: ""}
  72. }, {
  73. multi: true
  74. }, callback
  75. ensureIndices: () ->
  76. # For finding all updates that go into a diff for a doc
  77. db.docHistory.ensureIndex { doc_id: 1, v: 1 }, { background: true }
  78. # For finding all updates that affect a project
  79. db.docHistory.ensureIndex { project_id: 1, "meta.end_ts": 1 }, { background: true }
  80. # For finding updates that don't yet have a project_id and need it inserting
  81. db.docHistory.ensureIndex { doc_id: 1, project_id: 1 }, { background: true }
  82. # For finding project meta-data
  83. db.projectHistoryMetaData.ensureIndex { project_id: 1 }, { background: true }
  84. # TTL index for auto deleting week old temporary ops
  85. db.docHistory.ensureIndex { expiresAt: 1 }, { expireAfterSeconds: 0, background: true }
  86. # For finding packs to be checked for archiving
  87. db.docHistory.ensureIndex { last_checked: 1 }, { background: true }
  88. # For finding archived packs
  89. db.docHistoryIndex.ensureIndex { project_id: 1 }, { background: true }
  90. [
  91. 'getLastCompressedUpdate',
  92. 'getProjectMetaData',
  93. 'setProjectMetaData'
  94. ].map (method) ->
  95. metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger)