1_move_doc_lines_to_doc_collection.coffee 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. Settings = require "settings-sharelatex"
  2. bson = require('bson')
  3. BSON = new bson()
  4. fs = require("fs")
  5. mongojs = require("mongojs")
  6. ObjectId = mongojs.ObjectId
  7. console.log Settings.mongo.url
  8. db = mongojs(Settings.mongo.url, ['projects', 'docs'])
  9. _ = require("lodash")
  10. async = require("async")
  11. exec = require("child_process").exec
  12. finished_projects_path = "/tmp/finished-projects"
  13. all_projects_path = "/tmp/all-projects"
  14. project_too_large_path = "/tmp/large_projects"
  15. printProgress = ->
  16. exec "wc #{finished_projects_path}", (error, results) ->
  17. setTimeout printProgress, 1000 * 30
  18. checkIfFileHasBeenProcessed = (project_id, callback)->
  19. exec "grep #{project_id} #{finished_projects_path}", (error, results) ->
  20. hasBeenProcessed = _.include(results, project_id)
  21. callback(error, hasBeenProcessed)
  22. loadProjectIds = (callback)->
  23. console.log "loading project ids from #{all_projects_path}"
  24. fs.readFile all_projects_path, "utf-8", (err, data)->
  25. ids = data.split("\n")
  26. ids = _.filter ids, (id)-> id? and id.length == 24
  27. console.log "loaded #{ids.length} project ids from #{all_projects_path}"
  28. callback err, ids
  29. getAndWriteProjectids = (callback)->
  30. console.log "finding all project id's - #{new Date().toString()}"
  31. db.projects.find {}, {_id:1}, (err, ids)->
  32. console.log "total found projects in mongo #{ids.length} - #{new Date().toString()}"
  33. ids = _.pluck ids, '_id'
  34. ids = _.filter ids, (id)-> id?
  35. fileData = ids.join("\n")
  36. fs.writeFile all_projects_path, fileData, ->
  37. callback(err, ids)
  38. markProjectAsToLargeAndFinished = (project_id, callback)->
  39. console.log "#{project_id} too large"
  40. markProjectAsProcessed project_id, (err)->
  41. fs.appendFile project_too_large_path, "#{project_id}\n", callback
  42. getProjectIds = (callback)->
  43. exists = fs.existsSync all_projects_path
  44. if exists
  45. loadProjectIds callback
  46. else
  47. getAndWriteProjectids callback
  48. markProjectAsProcessed = (project_id, callback)->
  49. fs.appendFile finished_projects_path, "#{project_id}\n", callback
  50. getAllDocs = (project_id, callback = (error, docs) ->) ->
  51. db.projects.findOne _id:ObjectId(project_id), (error, project) ->
  52. return callback(error) if error?
  53. if !project?
  54. console.log "no such project #{project_id}"
  55. return callback()
  56. size = BSON.calculateObjectSize(project)
  57. if size > 12000000 #12mb
  58. return markProjectAsToLargeAndFinished project_id, callback
  59. findAllDocsInProject project, (error, docs) ->
  60. return callback(error) if error?
  61. return callback null, docs
  62. findAllDocsInProject = (project, callback = (error, docs) ->) ->
  63. callback null, _findAllDocsInFolder project.rootFolder[0]
  64. _findDocInFolder = (folder = {}, doc_id, currentPath) ->
  65. for doc, i in folder.docs or []
  66. if doc?._id? and doc._id.toString() == doc_id.toString()
  67. return {
  68. doc: doc
  69. mongoPath: "#{currentPath}.docs.#{i}"
  70. }
  71. for childFolder, i in folder.folders or []
  72. result = _findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}"
  73. return result if result?
  74. return null
  75. _findAllDocsInFolder = (folder = {}) ->
  76. docs = folder.docs or []
  77. for childFolder in folder.folders or []
  78. docs = docs.concat _findAllDocsInFolder childFolder
  79. return docs
  80. insertDocIntoDocCollection = (project_id, doc_id, lines, oldRev, callback)->
  81. if !project_id?
  82. return callback("no project id")
  83. if !doc_id?
  84. return callback()
  85. if !lines?
  86. lines = [""]
  87. update = {}
  88. update["_id"] = ObjectId(doc_id.toString())
  89. update["lines"] = lines
  90. update["project_id"] = ObjectId(project_id)
  91. update["rev"] = oldRev || 0
  92. db.docs.insert update, callback
  93. saveDocsIntoMongo = (project_id, docs, callback)->
  94. jobs = _.map docs, (doc)->
  95. (cb)->
  96. if !doc?
  97. console.error "null doc in project #{project_id}" #just skip it, not a big deal
  98. return cb()
  99. insertDocIntoDocCollection project_id, doc._id, doc.lines, doc.rev, (err)->
  100. if err?.code == 11000 #duplicate key, doc already in there so its not a problem.
  101. err = undefined
  102. if err?
  103. console.log "error inserting doc into doc collection", err
  104. cb(err)
  105. async.series jobs, callback
  106. processNext = (project_id, callback)->
  107. checkIfFileHasBeenProcessed project_id, (err, hasBeenProcessed)->
  108. if hasBeenProcessed
  109. console.log "#{project_id} already processed, skipping"
  110. return callback()
  111. console.log "#{project_id} processing"
  112. getAllDocs project_id, (err, docs)->
  113. if err?
  114. console.error err, project_id, "could not get all docs"
  115. return callback(err)
  116. else
  117. saveDocsIntoMongo project_id, docs, (err)->
  118. if err?
  119. console.error err, project_id, "could not save docs into mongo"
  120. return callback(err)
  121. markProjectAsProcessed project_id, (err)->
  122. setTimeout(
  123. -> callback(err)
  124. ,0)
  125. exports.migrate = (client, done = ->)->
  126. getProjectIds (err, ids)->
  127. printProgress()
  128. jobs = _.map ids, (id)->
  129. return (cb)->
  130. processNext(id, cb)
  131. async.series jobs, (err)->
  132. if err?
  133. console.error err, "at end of jobs"
  134. else
  135. console.log "finished"
  136. done(err)
  137. exports.rollback = (next)->
  138. next()