1_move_doc_lines_to_doc_collection.coffee 4.9 KB

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