diff --git a/src/posts/delete.js b/src/posts/delete.js index a77c153cb2..40b6554b6f 100644 --- a/src/posts/delete.js +++ b/src/posts/delete.js @@ -181,6 +181,9 @@ module.exports = function(Posts) { function(next) { db.sortedSetIncrBy('cid:' + topicData.cid + ':tids:posts', -1, postData.tid, next); }, + function(next) { + db.sortedSetIncrBy('tid:' + postData.tid + ':posters', -1, postData.uid, next); + }, function(next) { user.incrementUserPostCountBy(postData.uid, -1, next); } diff --git a/src/topics/delete.js b/src/topics/delete.js index 97d617d878..f979d3083a 100644 --- a/src/topics/delete.js +++ b/src/topics/delete.js @@ -1,12 +1,12 @@ 'use strict'; -var async = require('async'), - db = require('../database'), +var async = require('async'); +var db = require('../database'); - user = require('../user'), - posts = require('../posts'), - plugins = require('../plugins'), - batch = require('../batch'); +var user = require('../user'); +var posts = require('../posts'); +var plugins = require('../plugins'); +var batch = require('../batch'); module.exports = function(Topics) { @@ -115,7 +115,8 @@ module.exports = function(Topics) { 'tid:' + tid + ':followers', 'tid:' + tid + ':posts', 'tid:' + tid + ':posts:votes', - 'tid:' + tid + ':bookmarks' + 'tid:' + tid + ':bookmarks', + 'tid:' + tid + ':posters' ], next); }, function(next) { diff --git a/src/topics/fork.js b/src/topics/fork.js index 948cb3207e..80143e4d46 100644 --- a/src/topics/fork.js +++ b/src/topics/fork.js @@ -87,7 +87,7 @@ module.exports = function(Topics) { if (!exists) { return next(new Error('[[error:no-topic]]')); } - posts.getPostFields(pid, ['tid', 'timestamp', 'votes'], next); + posts.getPostFields(pid, ['tid', 'uid', 'timestamp', 'votes'], next); }, function(post, next) { if (!post || !post.tid) { @@ -101,7 +101,7 @@ module.exports = function(Topics) { postData = post; postData.pid = pid; - Topics.removePostFromTopic(postData.tid, pid, next); + Topics.removePostFromTopic(postData.tid, postData, next); }, function(next) { async.parallel([ @@ -118,7 +118,7 @@ module.exports = function(Topics) { posts.setPostField(pid, 'tid', tid, next); }, function(next) { - Topics.addPostToTopic(tid, pid, postData.timestamp, postData.votes, next); + Topics.addPostToTopic(tid, postData, next); } ], next); }, diff --git a/src/topics/posts.js b/src/topics/posts.js index 445eab4637..671c65b4c5 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -22,7 +22,7 @@ module.exports = function(Topics) { Topics.updateTimestamp(postData.tid, postData.timestamp, next); }, function(next) { - Topics.addPostToTopic(postData.tid, postData.pid, postData.timestamp, 0, next); + Topics.addPostToTopic(postData.tid, postData, next); } ], callback); }; @@ -264,38 +264,51 @@ module.exports = function(Topics) { ); }; - Topics.addPostToTopic = function(tid, pid, timestamp, votes, callback) { - Topics.getTopicField(tid, 'mainPid', function(err, mainPid) { - if (err) { - return callback(err); - } - if (!parseInt(mainPid, 10)) { - Topics.setTopicField(tid, 'mainPid', pid, callback); - } else { - async.parallel([ - function(next) { - db.sortedSetAdd('tid:' + tid + ':posts', timestamp, pid, next); - }, - function(next) { - db.sortedSetAdd('tid:' + tid + ':posts:votes', votes, pid, next); - } - ], function(err) { - if (err) { - return callback(err); - } - Topics.updateTeaser(tid, callback); - }); + Topics.addPostToTopic = function(tid, postData, callback) { + async.waterfall([ + function (next) { + Topics.getTopicField(tid, 'mainPid', next); + }, + function (mainPid, next) { + if (!parseInt(mainPid, 10)) { + Topics.setTopicField(tid, 'mainPid', postData.pid, next); + } else { + async.parallel([ + function(next) { + db.sortedSetAdd('tid:' + tid + ':posts', postData.timestamp, postData.pid, next); + }, + function(next) { + db.sortedSetAdd('tid:' + tid + ':posts:votes', postData.votes, postData.pid, next); + } + ], function(err) { + next(err); + }); + } + }, + function (next) { + db.sortedSetIncrBy('tid:' + tid + ':posters', 1, postData.uid, next); + }, + function (count, next) { + Topics.updateTeaser(tid, next); } - }); + ], callback); }; - Topics.removePostFromTopic = function(tid, pid, callback) { - db.sortedSetsRemove(['tid:' + tid + ':posts', 'tid:' + tid + ':posts:votes'], pid, function(err) { - if (err) { - return callback(err); + Topics.removePostFromTopic = function(tid, postData, callback) { + async.waterfall([ + function (next) { + db.sortedSetsRemove([ + 'tid:' + tid + ':posts', + 'tid:' + tid + ':posts:votes' + ], postData.pid, next); + }, + function (next) { + db.sortedSetIncrBy('tid:' + tid + ':posters', -1, postData.uid, next); + }, + function (count, next) { + Topics.updateTeaser(tid, next); } - Topics.updateTeaser(tid, callback); - }); + ], callback); }; Topics.getPids = function(tid, callback) { diff --git a/src/topics/user.js b/src/topics/user.js index 4db380efdf..09cb4a7e87 100644 --- a/src/topics/user.js +++ b/src/topics/user.js @@ -2,10 +2,9 @@ 'use strict'; -var async = require('async'), - db = require('../database'), - posts = require('../posts'); - +var async = require('async'); +var db = require('../database'); +var posts = require('../posts'); module.exports = function(Topics) { @@ -20,22 +19,6 @@ module.exports = function(Topics) { }; Topics.getUids = function(tid, callback) { - async.waterfall([ - function(next) { - Topics.getPids(tid, next); - }, - function(pids, next) { - posts.getPostsFields(pids, ['uid'], next); - }, - function(postData, next) { - var uids = postData.map(function(post) { - return post && post.uid; - }).filter(function(uid, index, array) { - return uid && array.indexOf(uid) === index; - }); - - next(null, uids); - } - ], callback); + db.getSortedSetRevRangeByScore('tid:' + tid + ':posters', 0, -1, '+inf', 1, callback); }; }; \ No newline at end of file diff --git a/src/upgrade.js b/src/upgrade.js index 68f830ef3c..77974839e6 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -10,7 +10,7 @@ var db = require('./database'), schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema - latestSchema = Date.UTC(2016, 3, 14); + latestSchema = Date.UTC(2016, 3, 18); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -476,6 +476,60 @@ Upgrade.upgrade = function(callback) { winston.info('[2016/04/14] Group title from settings to user profile skipped!'); next(); } + }, + function(next) { + thisSchemaDate = Date.UTC(2016, 3, 18); + + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.info('[2016/04/19] Users post count per tid'); + + var batch = require('./batch'); + var topics = require('./topics'); + var count = 0; + batch.processSortedSet('topics:tid', function(tids, next) { + winston.info('upgraded ' + count + ' topics'); + + async.each(tids, function(tid, next) { + db.delete('tid:' + tid + ':posters', function(err) { + if (err) { + return next(err); + } + topics.getPids(tid, function(err, pids) { + if (err) { + return next(err); + } + + if (!pids.length) { + return next(); + } + + async.eachSeries(pids, function(pid, next) { + db.getObjectField('post:' + pid, 'uid', function(err, uid) { + if (err) { + return next(err); + } + if (!parseInt(uid, 10)) { + return next(); + } + db.sortedSetIncrBy('tid:' + tid + ':posters', 1, uid, next); + }); + }, next); + }); + }); + }, next); + }, {}, function(err) { + if (err) { + return next(err); + } + + winston.info('[2016/04/19] Users post count per tid done'); + Upgrade.update(thisSchemaDate, next); + }); + } else { + winston.info('[2016/04/19] Users post count per tid skipped!'); + next(); + } } // Add new schema updates here // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 24!!!