diff --git a/services/web/app/src/infrastructure/mongodb.js b/services/web/app/src/infrastructure/mongodb.js index 408f174906..f7ce25759d 100644 --- a/services/web/app/src/infrastructure/mongodb.js +++ b/services/web/app/src/infrastructure/mongodb.js @@ -71,12 +71,7 @@ async function setupDb() { db.users = internalDb.collection('users') db.userstubs = internalDb.collection('userstubs') } -async function addCollection(name) { - await waitForDb() - const internalDb = (await clientPromise).db() - db[name] = internalDb.collection(name) -} async function getCollectionNames() { const internalDb = (await clientPromise).db() @@ -84,10 +79,18 @@ async function getCollectionNames() { return collections.map(collection => collection.collectionName) } +/** + * WARNING: Consider using a pre-populated collection from `db` to avoid typos! + */ +async function getCollectionInternal(name) { + const internalDb = (await clientPromise).db() + return internalDb.collection(name) +} + module.exports = { db, ObjectId, - addCollection, getCollectionNames, + getCollectionInternal, waitForDb, } diff --git a/services/web/migrations/20190912145022_create_projectImportFailures_indexes.js b/services/web/migrations/20190912145022_create_projectImportFailures_indexes.js index 979d63f2d1..75e6cc162b 100644 --- a/services/web/migrations/20190912145022_create_projectImportFailures_indexes.js +++ b/services/web/migrations/20190912145022_create_projectImportFailures_indexes.js @@ -1,6 +1,7 @@ /* eslint-disable no-unused-vars */ const Helpers = require('./lib/helpers') +const { getCollectionInternal } = require('../app/src/infrastructure/mongodb') exports.tags = ['saas'] @@ -13,17 +14,20 @@ const indexes = [ }, ] -exports.migrate = async client => { - const { db } = client +async function getCollection() { + // NOTE: This is a stale collection, it will get dropped in a later migration. + return await getCollectionInternal('projectImportFailures') +} - await Helpers.addIndexesToCollection(db.projectImportFailures, indexes) +exports.migrate = async client => { + const collection = await getCollection() + await Helpers.addIndexesToCollection(collection, indexes) } exports.rollback = async client => { - const { db } = client - + const collection = await getCollection() try { - await Helpers.dropIndexesFromCollection(db.projectImportFailures, indexes) + await Helpers.dropIndexesFromCollection(collection, indexes) } catch (err) { console.error('Something went wrong rolling back the migrations', err) } diff --git a/services/web/migrations/20191106102104_saml-log-indexes.js b/services/web/migrations/20191106102104_saml-log-indexes.js index 7526bcce70..c68d2752e2 100644 --- a/services/web/migrations/20191106102104_saml-log-indexes.js +++ b/services/web/migrations/20191106102104_saml-log-indexes.js @@ -1,6 +1,7 @@ /* eslint-disable no-unused-vars */ const Helpers = require('./lib/helpers') +const { getCollectionInternal } = require('../app/src/infrastructure/mongodb') exports.tags = ['saas'] @@ -27,17 +28,25 @@ const indexes = [ }, ] -exports.migrate = async client => { - const { db } = client +// Export indexes for use in the fix-up migration 20220105130000_fix_saml_indexes.js. +exports.samlLogsIndexes = indexes - await Helpers.addIndexesToCollection(db.samllog, indexes) +async function getCollection() { + // This collection was incorrectly named - it should have been `samlLogs` + // instead of `samllog`. The error is corrected by the subsequent migration + // 20220105130000_fix_saml_indexes.js. + return await getCollectionInternal('samllog') +} + +exports.migrate = async client => { + const collection = await getCollection() + await Helpers.addIndexesToCollection(collection, indexes) } exports.rollback = async client => { - const { db } = client - + const collection = await getCollection() try { - await Helpers.dropIndexesFromCollection(db.samllog, indexes) + await Helpers.dropIndexesFromCollection(collection, indexes) } catch (err) { console.error('Something went wrong rolling back the migrations', err) } diff --git a/services/web/migrations/20191107191318_saml-indentifiers-index.js b/services/web/migrations/20191107191318_saml-indentifiers-index.js index dde1d2f331..d5d75f2a40 100644 --- a/services/web/migrations/20191107191318_saml-indentifiers-index.js +++ b/services/web/migrations/20191107191318_saml-indentifiers-index.js @@ -1,6 +1,7 @@ /* eslint-disable no-unused-vars */ const Helpers = require('./lib/helpers') +const { getCollectionInternal } = require('../app/src/infrastructure/mongodb') exports.tags = ['saas'] @@ -15,17 +16,25 @@ const indexes = [ }, ] -exports.migrate = async client => { - const { db } = client +// Export indexes for use in the fix-up migration 20220105130000_fix_saml_indexes.js. +exports.usersIndexes = indexes - await Helpers.addIndexesToCollection(db.user, indexes) +async function getCollection() { + // This collection was incorrectly named - it should have been `users` instead + // of `user`. The error is corrected by the subsequent migration + // 20220105130000_fix_saml_indexes.js. + return await getCollectionInternal('user') +} + +exports.migrate = async client => { + const collection = await getCollection() + await Helpers.addIndexesToCollection(collection, indexes) } exports.rollback = async client => { - const { db } = client - + const collection = await getCollection() try { - await Helpers.dropIndexesFromCollection(db.user, indexes) + await Helpers.dropIndexesFromCollection(collection, indexes) } catch (err) { console.error('Something went wrong rolling back the migrations', err) } diff --git a/services/web/migrations/20200522145727_dropProjectImportFailures.js b/services/web/migrations/20200522145727_dropProjectImportFailures.js index 7e9e68d66d..503cac3d6f 100644 --- a/services/web/migrations/20200522145727_dropProjectImportFailures.js +++ b/services/web/migrations/20200522145727_dropProjectImportFailures.js @@ -3,8 +3,7 @@ const Helpers = require('./lib/helpers') exports.tags = ['saas'] exports.migrate = async client => { - const { db } = client - await Helpers.dropCollection(db, 'projectImportFailures') + await Helpers.dropCollection('projectImportFailures') } exports.rollback = async client => { diff --git a/services/web/migrations/20200522145741_dropProjectImportBatchRecords.js b/services/web/migrations/20200522145741_dropProjectImportBatchRecords.js index 6242d05680..46f1618c34 100644 --- a/services/web/migrations/20200522145741_dropProjectImportBatchRecords.js +++ b/services/web/migrations/20200522145741_dropProjectImportBatchRecords.js @@ -3,8 +3,7 @@ const Helpers = require('./lib/helpers') exports.tags = ['saas'] exports.migrate = async client => { - const { db } = client - await Helpers.dropCollection(db, 'projectImportBatchRecords') + await Helpers.dropCollection('projectImportBatchRecords') } exports.rollback = async client => { diff --git a/services/web/migrations/20210924140139_splittests-name-index.js b/services/web/migrations/20210924140139_splittests-name-index.js index 67d99e244f..169576eb0c 100644 --- a/services/web/migrations/20210924140139_splittests-name-index.js +++ b/services/web/migrations/20210924140139_splittests-name-index.js @@ -1,4 +1,5 @@ const Helpers = require('./lib/helpers') +const { getCollectionInternal } = require('../app/src/infrastructure/mongodb') exports.tags = ['saas'] @@ -12,12 +13,17 @@ const indexes = [ }, ] +async function getCollection() { + // NOTE: We do not access the splittests collection directly. Fetch it here. + return await getCollectionInternal('splittests') +} + exports.migrate = async client => { - const { db } = client - await Helpers.addIndexesToCollection(db.splittests, indexes) + const collection = await getCollection() + await Helpers.addIndexesToCollection(collection, indexes) } exports.rollback = async client => { - const { db } = client - Helpers.dropIndexesFromCollection(db.splittests, indexes) + const collection = await getCollection() + await Helpers.dropIndexesFromCollection(collection, indexes) } diff --git a/services/web/migrations/20220105123000_cleanup_unused_collections.js b/services/web/migrations/20220105123000_cleanup_unused_collections.js new file mode 100644 index 0000000000..9a249ec236 --- /dev/null +++ b/services/web/migrations/20220105123000_cleanup_unused_collections.js @@ -0,0 +1,29 @@ +const Helpers = require('./lib/helpers') + +exports.tags = ['saas'] + +const unusedCollections = [ + 'collaberatorcount', + 'db.subscriptions', + 'projectsDeletedByMigration', + 'readonlycount', + 'samllog', + 'sharelatex-production.docOps.2013-12-17T02-26-49.0', + 'sharelatex-production.projects.2013-12-17T02-26-49.1', + 'sharelatex-production.users.2013-12-17T02-26-49.2', + 'sharelatex_production.users', + 'totalwords', + 'user', + 'usersDeletedByMigration', + 'usersEmailDomains', +] + +exports.migrate = async () => { + for (const name of unusedCollections) { + await Helpers.dropCollection(name) + } +} + +exports.rollback = async () => { + // We lost the indexes. There is no way back. +} diff --git a/services/web/migrations/20220105130000_fix_saml_indexes.js b/services/web/migrations/20220105130000_fix_saml_indexes.js new file mode 100644 index 0000000000..263061fdcb --- /dev/null +++ b/services/web/migrations/20220105130000_fix_saml_indexes.js @@ -0,0 +1,14 @@ +const Helpers = require('./lib/helpers') +const { samlLogsIndexes } = require('./20191106102104_saml-log-indexes') +const { usersIndexes } = require('./20191107191318_saml-indentifiers-index') + +exports.tags = ['saas'] + +exports.migrate = async ({ db }) => { + // Fix-up the previous SAML migrations that were operating on collections with + // typos in their names. + await Helpers.addIndexesToCollection(db.users, usersIndexes) + await Helpers.addIndexesToCollection(db.samlLogs, samlLogsIndexes) +} + +exports.rollback = async () => {} diff --git a/services/web/migrations/lib/adapter.js b/services/web/migrations/lib/adapter.js index eb7757e2f4..589d714ff9 100644 --- a/services/web/migrations/lib/adapter.js +++ b/services/web/migrations/lib/adapter.js @@ -1,9 +1,5 @@ const Path = require('path') -const { - addCollection, - waitForDb, - db, -} = require('../../app/src/infrastructure/mongodb') +const { waitForDb, db } = require('../../app/src/infrastructure/mongodb') class Adapter { constructor(params) { @@ -24,12 +20,6 @@ class Adapter { async connect() { await waitForDb() - - await addCollection('projectImportFailures') - await addCollection('samllog') - await addCollection('user') - await addCollection('splittests') - return { db } } diff --git a/services/web/migrations/lib/helpers.js b/services/web/migrations/lib/helpers.js index 9b56065309..8be0393ec2 100644 --- a/services/web/migrations/lib/helpers.js +++ b/services/web/migrations/lib/helpers.js @@ -1,4 +1,9 @@ -const { getCollectionNames } = require('../../app/src/infrastructure/mongodb') +const { + db, + getCollectionNames, + getCollectionInternal, + waitForDb, +} = require('../../app/src/infrastructure/mongodb') async function addIndexesToCollection(collection, indexes) { return Promise.all( @@ -13,10 +18,16 @@ async function dropIndexesFromCollection(collection, indexes) { return Promise.all(indexes.map(index => collection.dropIndex(index.name))) } -async function dropCollection(db, collectionName) { +async function dropCollection(collectionName) { + await waitForDb() + if (db[collectionName]) { + throw new Error(`blocking drop of an active collection: ${collectionName}`) + } + const allCollections = await getCollectionNames() if (!allCollections.includes(collectionName)) return - return db[collectionName].drop() + const collection = await getCollectionInternal(collectionName) + await collection.drop() } module.exports = { diff --git a/services/web/migrations/lib/template.js b/services/web/migrations/lib/template.js index fb1c009c1b..3505b5ddb6 100644 --- a/services/web/migrations/lib/template.js +++ b/services/web/migrations/lib/template.js @@ -11,5 +11,5 @@ exports.migrate = async client => { exports.rollback = async client => { const { db } = client - // Helpers.dropIndexesFromCollection(db.wombats, [{ name: 1 }]) + // await Helpers.dropIndexesFromCollection(db.wombats, [{ name: 1 }]) }