MongoManager.coffee 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. {db, ObjectId} = require "./mongojs"
  2. PackManager = require "./PackManager"
  3. async = require "async"
  4. module.exports = MongoManager =
  5. getLastCompressedUpdate: (doc_id, callback = (error, update) ->) ->
  6. db.docHistory
  7. .find(doc_id: ObjectId(doc_id.toString()))
  8. .sort( v: -1 )
  9. .limit(1)
  10. .toArray (error, compressedUpdates) ->
  11. return callback(error) if error?
  12. if compressedUpdates[0]?.pack?
  13. # cannot pop from a pack, throw error
  14. error = new Error("last compressed update is a pack")
  15. return callback error, null
  16. return callback null, compressedUpdates[0] or null
  17. deleteCompressedUpdate: (id, callback = (error) ->) ->
  18. db.docHistory.remove({ _id: ObjectId(id.toString()) }, callback)
  19. popLastCompressedUpdate: (doc_id, callback = (error, update) ->) ->
  20. MongoManager.getLastCompressedUpdate doc_id, (error, update) ->
  21. return callback(error) if error?
  22. if update?
  23. MongoManager.deleteCompressedUpdate update._id, (error) ->
  24. return callback(error) if error?
  25. callback null, update
  26. else
  27. callback null, null
  28. insertCompressedUpdates: (project_id, doc_id, updates, temporary, callback = (error) ->) ->
  29. jobs = []
  30. for update in updates
  31. do (update) ->
  32. jobs.push (callback) -> MongoManager.insertCompressedUpdate project_id, doc_id, update, temporary, callback
  33. async.series jobs, (err, results) ->
  34. if not temporary
  35. # keep track of updates to be packed
  36. db.docHistoryStats.update {doc_id:ObjectId(doc_id)}, {
  37. $inc:{update_count:updates.length},
  38. $currentDate:{last_update:true}
  39. }, {upsert:true}, () ->
  40. callback(err,results)
  41. else
  42. callback(err,results)
  43. insertCompressedUpdate: (project_id, doc_id, update, temporary, callback = (error) ->) ->
  44. update = {
  45. doc_id: ObjectId(doc_id.toString())
  46. project_id: ObjectId(project_id.toString())
  47. op: update.op
  48. meta: update.meta
  49. v: update.v
  50. }
  51. if temporary
  52. seconds = 1000
  53. minutes = 60 * seconds
  54. hours = 60 * minutes
  55. days = 24 * hours
  56. update.expiresAt = new Date(Date.now() + 7 * days)
  57. # may need to roll over a pack here if we are inserting packs
  58. db.docHistory.insert update, callback
  59. getDocUpdates:(doc_id, options = {}, callback = (error, updates) ->) ->
  60. query =
  61. doc_id: ObjectId(doc_id.toString())
  62. if options.from?
  63. query["v"] ||= {}
  64. query["v"]["$gte"] = options.from
  65. if options.to?
  66. query["v"] ||= {}
  67. query["v"]["$lte"] = options.to
  68. PackManager.findDocResults(db.docHistory, query, options.limit, callback)
  69. getProjectUpdates: (project_id, options = {}, callback = (error, updates) ->) ->
  70. query =
  71. project_id: ObjectId(project_id.toString())
  72. if options.before?
  73. query["meta.end_ts"] = { $lt: options.before }
  74. PackManager.findProjectResults(db.docHistory, query, options.limit, callback)
  75. backportProjectId: (project_id, doc_id, callback = (error) ->) ->
  76. db.docHistory.update {
  77. doc_id: ObjectId(doc_id.toString())
  78. project_id: { $exists: false }
  79. }, {
  80. $set: { project_id: ObjectId(project_id.toString()) }
  81. }, {
  82. multi: true
  83. }, callback
  84. getProjectMetaData: (project_id, callback = (error, metadata) ->) ->
  85. db.projectHistoryMetaData.find {
  86. project_id: ObjectId(project_id.toString())
  87. }, (error, results) ->
  88. return callback(error) if error?
  89. callback null, results[0]
  90. setProjectMetaData: (project_id, metadata, callback = (error) ->) ->
  91. db.projectHistoryMetaData.update {
  92. project_id: ObjectId(project_id)
  93. }, {
  94. $set: metadata
  95. }, {
  96. upsert: true
  97. }, callback
  98. ensureIndices: () ->
  99. # For finding all updates that go into a diff for a doc
  100. db.docHistory.ensureIndex { doc_id: 1, v: 1 }, { background: true }
  101. # For finding all updates that affect a project
  102. db.docHistory.ensureIndex { project_id: 1, "meta.end_ts": 1 }, { background: true }
  103. # For finding all packs that affect a project (use a sparse index so only packs are included)
  104. db.docHistory.ensureIndex { project_id: 1, "pack.0.meta.end_ts": 1, "meta.end_ts": 1}, { background: true, sparse: true }
  105. # For finding updates that don't yet have a project_id and need it inserting
  106. db.docHistory.ensureIndex { doc_id: 1, project_id: 1 }, { background: true }
  107. # For finding project meta-data
  108. db.projectHistoryMetaData.ensureIndex { project_id: 1 }, { background: true }
  109. # TTL index for auto deleting week old temporary ops
  110. db.docHistory.ensureIndex { expiresAt: 1 }, { expireAfterSeconds: 0, background: true }
  111. # For finding documents which need packing
  112. db.docHistoryStats.ensureIndex { doc_id: 1 }, { background: true }
  113. db.docHistoryStats.ensureIndex { updates: -1, doc_id: 1 }, { background: true }