helpers.mjs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // @ts-check
  2. import {
  3. db,
  4. getCollectionNames,
  5. getCollectionInternal,
  6. } from '../../app/src/infrastructure/mongodb.js'
  7. /**
  8. * @typedef {import('mongodb-legacy').Document} Collection
  9. * @typedef {import('mongodb-legacy').Collection<Document>} Collection
  10. */
  11. /**
  12. * @param {Collection} collection
  13. * @param {Array<{ name: string }>} indexes
  14. * @return {Promise<void>}
  15. */
  16. async function addIndexesToCollection(collection, indexes) {
  17. await Promise.all(
  18. indexes.map(index => {
  19. index.background = true
  20. return collection.createIndex(index.key, index)
  21. })
  22. )
  23. }
  24. /**
  25. * @param {Collection} collection
  26. * @param {Array<{ name: string }>} indexes
  27. * @return {Promise<void>}
  28. */
  29. async function dropIndexesFromCollection(collection, indexes) {
  30. await Promise.all(
  31. indexes.map(async index => {
  32. try {
  33. await collection.dropIndex(index.name)
  34. } catch (err) {
  35. if (err.code === 27 /* IndexNotFound */) {
  36. console.log(`Index ${index.name} not found; drop was a no-op.`)
  37. } else {
  38. throw err
  39. }
  40. }
  41. })
  42. )
  43. }
  44. /**
  45. * @param {string} collectionName
  46. * @return {Promise<void>}
  47. */
  48. async function dropCollection(collectionName) {
  49. if (db[collectionName]) {
  50. throw new Error(`blocking drop of an active collection: ${collectionName}`)
  51. }
  52. const allCollections = await getCollectionNames()
  53. if (!allCollections.includes(collectionName)) return
  54. const collection = await getCollectionInternal(collectionName)
  55. await collection.drop()
  56. }
  57. class BadMigrationOrder extends Error {}
  58. /**
  59. * Asserts that a dependent migration has run. Throws an error otherwise.
  60. *
  61. * @param {string} migrationName
  62. */
  63. async function assertDependency(migrationName) {
  64. const migrations = await getCollectionInternal('migrations')
  65. const migration = await migrations.findOne({ name: migrationName })
  66. if (migration == null) {
  67. throw new BadMigrationOrder(
  68. `${migrationName} should run before this migration`
  69. )
  70. }
  71. }
  72. export default {
  73. BadMigrationOrder,
  74. addIndexesToCollection,
  75. dropIndexesFromCollection,
  76. dropCollection,
  77. assertDependency,
  78. }