find_malformed_filetrees.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. const { ReadPreference } = require('mongodb')
  2. const { db, waitForDb } = require('../app/src/infrastructure/mongodb')
  3. async function main() {
  4. await waitForDb()
  5. const projects = db.projects.find(
  6. {},
  7. { projection: { rootFolder: 1 }, readPreference: ReadPreference.SECONDARY }
  8. )
  9. let projectsProcessed = 0
  10. for await (const project of projects) {
  11. projectsProcessed += 1
  12. if (projectsProcessed % 100000 === 0) {
  13. console.log(projectsProcessed, 'projects processed')
  14. }
  15. processProject(project)
  16. }
  17. }
  18. function processProject(project) {
  19. if (!project.rootFolder || !Array.isArray(project.rootFolder)) {
  20. console.log('BAD PATH:', project._id, 'rootFolder')
  21. return
  22. }
  23. if (!project.rootFolder[0]) {
  24. console.log('BAD PATH:', project._id, 'rootFolder.0')
  25. return
  26. }
  27. const badPaths = findBadPaths(project.rootFolder[0])
  28. for (const path of badPaths) {
  29. console.log('BAD PATH:', project._id, `rootFolder.0.${path}`)
  30. }
  31. }
  32. function findBadPaths(folder) {
  33. const result = []
  34. if (!folder._id) {
  35. result.push('_id')
  36. }
  37. if (typeof folder.name !== 'string' || !folder.name) {
  38. result.push('name')
  39. }
  40. if (folder.folders) {
  41. if (Array.isArray(folder.folders)) {
  42. for (const [i, subfolder] of folder.folders.entries()) {
  43. if (!subfolder || typeof subfolder !== 'object') {
  44. result.push(`folders.${i}`)
  45. continue
  46. }
  47. for (const badPath of findBadPaths(subfolder)) {
  48. result.push(`folders.${i}.${badPath}`)
  49. }
  50. }
  51. } else {
  52. result.push('folders')
  53. }
  54. }
  55. if (folder.docs) {
  56. if (Array.isArray(folder.docs)) {
  57. for (const [i, doc] of folder.docs.entries()) {
  58. if (!doc || typeof doc !== 'object') {
  59. result.push(`docs.${i}`)
  60. continue
  61. }
  62. if (!doc._id) {
  63. result.push(`docs.${i}._id`)
  64. // no need to check further: this doc can be deleted
  65. continue
  66. }
  67. if (typeof doc.name !== 'string' || !doc.name) {
  68. result.push(`docs.${i}.name`)
  69. }
  70. }
  71. } else {
  72. result.push('docs')
  73. }
  74. }
  75. if (folder.fileRefs) {
  76. if (Array.isArray(folder.fileRefs)) {
  77. for (const [i, file] of folder.fileRefs.entries()) {
  78. if (!file || typeof file !== 'object') {
  79. result.push(`fileRefs.${i}`)
  80. continue
  81. }
  82. if (!file._id) {
  83. result.push(`fileRefs.${i}._id`)
  84. // no need to check further: this file can be deleted
  85. continue
  86. }
  87. if (typeof file.name !== 'string' || !file.name) {
  88. result.push(`fileRefs.${i}.name`)
  89. }
  90. }
  91. } else {
  92. result.push('fileRefs')
  93. }
  94. }
  95. return result
  96. }
  97. main()
  98. .then(() => {
  99. process.exit(0)
  100. })
  101. .catch(err => {
  102. console.error(err)
  103. process.exit(1)
  104. })