/* eslint-disable camelcase, no-unused-vars, */ // TODO: This file was created by bulk-decaffeinate. // Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ let MongoManager const { db, ObjectId } = require('./mongodb') const PackManager = require('./PackManager') const async = require('async') const _ = require('underscore') const metrics = require('@overleaf/metrics') const logger = require('@overleaf/logger') module.exports = MongoManager = { getLastCompressedUpdate(doc_id, callback) { if (callback == null) { callback = function () {} } return db.docHistory .find( { doc_id: ObjectId(doc_id.toString()) }, // only return the last entry in a pack { projection: { pack: { $slice: -1 } } } ) .sort({ v: -1 }) .limit(1) .toArray(function (error, compressedUpdates) { if (error != null) { return callback(error) } return callback(null, compressedUpdates[0] || null) }) }, peekLastCompressedUpdate(doc_id, callback) { // under normal use we pass back the last update as // callback(null,update,version). // // when we have an existing last update but want to force a new one // to start, we pass it back as callback(null,null,version), just // giving the version so we can check consistency. if (callback == null) { callback = function () {} } return MongoManager.getLastCompressedUpdate( doc_id, function (error, update) { if (error != null) { return callback(error) } if (update != null) { if (update.broken) { // marked as broken so we will force a new op return callback(null, null) } else if (update.pack != null) { if (update.finalised) { // no more ops can be appended return callback( null, null, update.pack[0] != null ? update.pack[0].v : undefined ) } else { return callback( null, update, update.pack[0] != null ? update.pack[0].v : undefined ) } } else { return callback(null, update, update.v) } } else { return PackManager.getLastPackFromIndex( doc_id, function (error, pack) { if (error != null) { return callback(error) } if ( (pack != null ? pack.inS3 : undefined) != null && (pack != null ? pack.v_end : undefined) != null ) { return callback(null, null, pack.v_end) } return callback(null, null) } ) } } ) }, backportProjectId(project_id, doc_id, callback) { if (callback == null) { callback = function () {} } return db.docHistory.updateMany( { doc_id: ObjectId(doc_id.toString()), project_id: { $exists: false }, }, { $set: { project_id: ObjectId(project_id.toString()) }, }, callback ) }, getProjectMetaData(project_id, callback) { if (callback == null) { callback = function () {} } return db.projectHistoryMetaData.findOne( { project_id: ObjectId(project_id.toString()), }, callback ) }, setProjectMetaData(project_id, metadata, callback) { if (callback == null) { callback = function () {} } return db.projectHistoryMetaData.updateOne( { project_id: ObjectId(project_id), }, { $set: metadata, }, { upsert: true, }, callback ) }, upgradeHistory(project_id, callback) { // preserve the project's existing history if (callback == null) { callback = function () {} } return db.docHistory.updateMany( { project_id: ObjectId(project_id), temporary: true, expiresAt: { $exists: true }, }, { $set: { temporary: false }, $unset: { expiresAt: '' }, }, callback ) }, ensureIndices() { // For finding all updates that go into a diff for a doc db.docHistory.ensureIndex({ doc_id: 1, v: 1 }, { background: true }) // For finding all updates that affect a project db.docHistory.ensureIndex( { project_id: 1, 'meta.end_ts': 1 }, { background: true } ) // For finding updates that don't yet have a project_id and need it inserting db.docHistory.ensureIndex( { doc_id: 1, project_id: 1 }, { background: true } ) // For finding project meta-data db.projectHistoryMetaData.ensureIndex( { project_id: 1 }, { background: true } ) // TTL index for auto deleting week old temporary ops db.docHistory.ensureIndex( { expiresAt: 1 }, { expireAfterSeconds: 0, background: true } ) // For finding packs to be checked for archiving db.docHistory.ensureIndex({ last_checked: 1 }, { background: true }) // For finding archived packs return db.docHistoryIndex.ensureIndex( { project_id: 1 }, { background: true } ) }, } ;['getLastCompressedUpdate', 'getProjectMetaData', 'setProjectMetaData'].map( method => metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger) )