diff --git a/bin/cli-users b/bin/cli-users index 6e901f529..ea308ae44 100755 --- a/bin/cli-users +++ b/bin/cli-users @@ -8,6 +8,7 @@ const util = require('./util'); const program = require('commander'); const inquirer = require('inquirer'); const { graphql } = require('graphql'); +const helpers = require('../services/migration/helpers'); const { stripIndent } = require('common-tags'); const Table = require('cli-table'); @@ -28,11 +29,23 @@ const CommentModel = require('../models/comment'); const ActionModel = require('../models/action'); const USER_ROLES = require('../models/enum/user_roles'); const mongoose = require('../services/mongoose'); -const databaseVerifications = require('./verifications/database'); // Register the shutdown criteria. util.onshutdown([() => mongoose.disconnect()]); +/** + * transforms a specific action to a removal action on the target model. + */ +const actionDecrTransformer = ({ item_id, action_type, group_id }) => ({ + query: { id: item_id }, + update: { + $inc: { + [`action_counts.${action_type.toLowerCase()}`]: -1, + [`action_counts.${action_type.toLowerCase()}_${group_id.toLowerCase()}`]: -1, + }, + }, +}); + /** * Deletes a user and cleans up their associated verifications. */ @@ -63,8 +76,27 @@ async function deleteUser(userID) { return util.shutdown(); } + const { transformSingleWithCursor } = helpers({ + queryBatchSize: 10000, + updateBatchSize: 10000, + }); + console.warn("Removing user's actions"); + // Remove all actions against comments. + await transformSingleWithCursor( + ActionModel.collection.find({ user_id: user.id, item_type: 'COMMENTS' }), + actionDecrTransformer, + CommentModel + ); + + // Remove all actions against users. + await transformSingleWithCursor( + ActionModel.collection.find({ user_id: user.id, item_type: 'USERS' }), + actionDecrTransformer, + UserModel + ); + // Remove all the user's actions. await ActionModel.where({ user_id: user.id }) .setOptions({ multi: true }) @@ -72,18 +104,34 @@ async function deleteUser(userID) { console.warn("Removing user's comments"); + // Removes all the user's reply counts on each of the comments that they + // have commented on. + await transformSingleWithCursor( + CommentModel.collection.aggregate([ + { $match: { author_id: user.id } }, + { + $group: { + _id: '$parent_id', + count: { $sum: 1 }, + }, + }, + ]), + ({ _id: parent_id, count }) => ({ + query: { id: parent_id }, + update: { + $inc: { + reply_count: -1 * count, + }, + }, + }), + CommentModel + ); + // Remove all the user's comments. await CommentModel.where({ author_id: user.id }) .setOptions({ multi: true }) .remove(); - console.warn('Updating the database indexes'); - - // Update the counts that might have changed. - for (const verification of databaseVerifications) { - await verification({ fix: true, limit: Infinity, batch: 1000 }); - } - console.warn('Removing the user'); // Remove the user.