DocManager.coffee 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. MongoManager = require "./MongoManager"
  2. Errors = require "./Errors"
  3. logger = require "logger-sharelatex"
  4. _ = require "underscore"
  5. DocArchive = require "./DocArchiveManager"
  6. RangeManager = require "./RangeManager"
  7. module.exports = DocManager =
  8. # TODO: For historical reasons, the doc version is currently stored in the docOps
  9. # collection (which is all that this collection contains). In future, we should
  10. # migrate this version property to be part of the docs collection, to guarantee
  11. # consitency between lines and version when writing/reading, and for a simpler schema.
  12. _getDoc: (project_id, doc_id, filter = {}, callback = (error, doc) ->) ->
  13. if filter.inS3 != true
  14. return callback("must include inS3 when getting doc")
  15. MongoManager.findDoc project_id, doc_id, filter, (err, doc)->
  16. if err?
  17. return callback(err)
  18. else if !doc?
  19. return callback new Errors.NotFoundError("No such doc: #{doc_id} in project #{project_id}")
  20. else if doc?.inS3
  21. DocArchive.unarchiveDoc project_id, doc_id, (err)->
  22. if err?
  23. logger.err err:err, project_id:project_id, doc_id:doc_id, "error unarchiving doc"
  24. return callback(err)
  25. DocManager._getDoc project_id, doc_id, filter, callback
  26. else
  27. if filter.version
  28. MongoManager.getDocVersion doc_id, (error, version) ->
  29. return callback(error) if error?
  30. doc.version = version
  31. callback err, doc
  32. else
  33. callback err, doc
  34. checkDocExists: (project_id, doc_id, callback = (err, exists)->)->
  35. DocManager._getDoc project_id, doc_id, {_id:1, inS3:true}, (err, doc)->
  36. if err?
  37. return callback(err)
  38. callback(err, doc?)
  39. getFullDoc: (project_id, doc_id, callback = (err, doc)->)->
  40. DocManager._getDoc project_id, doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}, (err, doc)->
  41. if err?
  42. return callback(err)
  43. callback(err, doc)
  44. getDocLines: (project_id, doc_id, callback = (err, doc)->)->
  45. DocManager._getDoc project_id, doc_id, {lines:true, inS3:true}, (err, doc)->
  46. if err?
  47. return callback(err)
  48. callback(err, doc)
  49. getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) ->
  50. DocArchive.unArchiveAllDocs project_id, (error) ->
  51. if error?
  52. return callback(error)
  53. MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) ->
  54. if err?
  55. return callback(error)
  56. else if !docs?
  57. return callback new Errors.NotFoundError("No docs for project #{project_id}")
  58. else
  59. return callback(null, docs)
  60. updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) ->
  61. if !lines? or !version? or !ranges?
  62. return callback(new Error("no lines, version or ranges provided"))
  63. DocManager._getDoc project_id, doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}, (err, doc)->
  64. if err? and !(err instanceof Errors.NotFoundError)
  65. logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update"
  66. return callback(err)
  67. ranges = RangeManager.jsonRangesToMongo(ranges)
  68. if !doc?
  69. # If the document doesn't exist, we'll make sure to create/update all parts of it.
  70. updateLines = true
  71. updateVersion = true
  72. updateRanges = true
  73. else
  74. updateLines = not _.isEqual(doc.lines, lines)
  75. updateVersion = (doc.version != version)
  76. updateRanges = RangeManager.shouldUpdateRanges(doc.ranges, ranges)
  77. modified = false
  78. rev = doc?.rev || 0
  79. updateLinesAndRangesIfNeeded = (cb) ->
  80. if updateLines or updateRanges
  81. update = {}
  82. if updateLines
  83. update.lines = lines
  84. if updateRanges
  85. update.ranges = ranges
  86. logger.log { project_id, doc_id }, "updating doc lines and ranges"
  87. modified = true
  88. rev += 1 # rev will be incremented in mongo by MongoManager.upsertIntoDocCollection
  89. MongoManager.upsertIntoDocCollection project_id, doc_id, update, cb
  90. else
  91. logger.log { project_id, doc_id, }, "doc lines have not changed - not updating"
  92. cb()
  93. updateVersionIfNeeded = (cb) ->
  94. if updateVersion
  95. logger.log { project_id, doc_id, oldVersion: doc?.version, newVersion: version }, "updating doc version"
  96. modified = true
  97. MongoManager.setDocVersion doc_id, version, cb
  98. else
  99. logger.log { project_id, doc_id, version }, "doc version has not changed - not updating"
  100. cb()
  101. updateLinesAndRangesIfNeeded (error) ->
  102. return callback(error) if error?
  103. updateVersionIfNeeded (error) ->
  104. return callback(error) if error?
  105. callback null, modified, rev
  106. deleteDoc: (project_id, doc_id, callback = (error) ->) ->
  107. DocManager.checkDocExists project_id, doc_id, (error, exists) ->
  108. return callback(error) if error?
  109. return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !exists
  110. MongoManager.markDocAsDeleted project_id, doc_id, callback