find_malformed_filetrees.mjs 2.7 KB

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