diff --git a/src/categories.js b/src/categories.js index 10ff73f894..58c790c1a4 100644 --- a/src/categories.js +++ b/src/categories.js @@ -41,6 +41,7 @@ var db = require('./database'), color: data.color, slug: slug, topic_count: 0, + post_count: 0, disabled: 0, order: data.order, link: '', @@ -173,10 +174,6 @@ var db = require('./database'), }); }; - Categories.getPostCount = function(cid, callback) { - db.sortedSetCard('categories:recent_posts:cid:' + cid, callback); - }; - Categories.getAllCategories = function(callback) { db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { if (err) { @@ -290,13 +287,7 @@ var db = require('./database'), category.description = validator.escape(category.description); category.backgroundImage = category.image ? nconf.get('relative_path') + category.image : ''; category.disabled = category.disabled ? parseInt(category.disabled, 10) !== 0 : false; - Categories.getPostCount(category.cid, function(err, postCount) { - if (err) { - return next(err); - } - category.post_count = postCount; - next(err, category); - }); + next(null, category); }, callback); }); }; @@ -355,6 +346,7 @@ var db = require('./database'), var cid = topicData.cid; db.sortedSetAdd('categories:recent_posts:cid:' + cid, postData.timestamp, postData.pid); + db.incrObjectField('category:' + cid, 'post_count'); if(parseInt(topicData.pinned, 10) === 0) { db.sortedSetAdd('categories:' + cid + ':tid', postData.timestamp, postData.tid); diff --git a/src/categories/recentreplies.js b/src/categories/recentreplies.js index 8142a06c24..72e47f4f05 100644 --- a/src/categories/recentreplies.js +++ b/src/categories/recentreplies.js @@ -35,6 +35,8 @@ module.exports = function(Categories) { ], next); } + updatePostCount(tid, oldCid, cid); + topics.getPids(tid, function(err, pids) { if (err) { return winston.error(err.message); @@ -60,6 +62,25 @@ module.exports = function(Categories) { }); }); }; + + function updatePostCount(tid, oldCid, newCid) { + topics.getTopicField(tid, 'postcount', function(err, postCount) { + if (err) { + return winston.error(err.message); + } + + async.parallel([ + function(next) { + db.incrObjectFieldBy('category:' + oldCid, 'post_count', -postCount, next); + }, + function(next) { + db.incrObjectFieldBy('category:' + newCid, 'post_count', postCount, next); + } + ], function(err) { + winston.error(err.message); + }); + }); + } }; diff --git a/src/postTools.js b/src/postTools.js index 341405648a..666d55f8b9 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -138,7 +138,7 @@ var winston = require('winston'), db.incrObjectFieldBy('global', 'postCount', isDelete ? -1 : 1); - posts.getPostFields(pid, ['pid', 'tid', 'uid', 'content'], function(err, postData) { + posts.getPostFields(pid, ['pid', 'tid', 'uid', 'content', 'timestamp'], function(err, postData) { if (err) { return callback(err); } @@ -160,7 +160,7 @@ var winston = require('winston'), updateTopicTimestamp(postData.tid, next); }, function(next) { - addOrRemoveFromCategoryRecentPosts(pid, postData.tid, isDelete, next); + addOrRemoveFromCategory(pid, postData.tid, postData.timestamp, isDelete, next); } ], function(err) { if (!isDelete) { @@ -206,23 +206,19 @@ var winston = require('winston'), }); } - function addOrRemoveFromCategoryRecentPosts(pid, tid, isDelete, callback) { + function addOrRemoveFromCategory(pid, tid, timestamp, isDelete, callback) { topics.getTopicField(tid, 'cid', function(err, cid) { if (err) { return callback(err); } - posts.getPostField(pid, 'timestamp', function(err, timestamp) { - if (err) { - return callback(err); - } + db.incrObjectFieldBy('category:' + cid, 'post_count', isDelete ? -1 : 1); - if (isDelete) { - db.sortedSetRemove('categories:recent_posts:cid:' + cid, pid, callback); - } else { - db.sortedSetAdd('categories:recent_posts:cid:' + cid, timestamp, pid, callback); - } - }); + if (isDelete) { + db.sortedSetRemove('categories:recent_posts:cid:' + cid, pid, callback); + } else { + db.sortedSetAdd('categories:recent_posts:cid:' + cid, timestamp, pid, callback); + } }); } diff --git a/src/posts/delete.js b/src/posts/delete.js index d3d153b9a3..664d0b4fea 100644 --- a/src/posts/delete.js +++ b/src/posts/delete.js @@ -55,13 +55,23 @@ module.exports = function(Posts) { return callback(err); } - topics.getTopicFields(postData.tid, ['deleted'], function(err, topicData) { + topics.getTopicFields(postData.tid, ['cid', 'deleted'], function(err, topicData) { if (err) { return callback(err); } if (parseInt(postData.deleted, 10) === 0 && parseInt(topicData.deleted, 10) !== 1) { - db.decrObjectField('global', 'postCount', callback); + async.parallel([ + function (next) { + db.decrObjectField('global', 'postCount', next); + }, + function (next) { + db.decrObjectField('category:' + topicData.cid, 'post_count', next); + }, + function (next) { + db.decrObjectField('topic:' + postData.tid, 'postcount', next); + } + ], callback); } else { callback(); } diff --git a/src/topics.js b/src/topics.js index ed31a33578..52572d729e 100644 --- a/src/topics.js +++ b/src/topics.js @@ -426,15 +426,4 @@ var async = require('async'), }); }; - Topics.updateTopicCount = function(callback) { - db.sortedSetCard('topics:recent', function(err, count) { - if(err) { - return callback(err); - } - - db.setObjectField('global', 'topicCount', count, callback); - }); - }; - - }(exports)); diff --git a/src/topics/delete.js b/src/topics/delete.js index e378bae04c..c1966bd7b2 100644 --- a/src/topics/delete.js +++ b/src/topics/delete.js @@ -8,18 +8,28 @@ var async = require('async'), module.exports = function(Topics) { - function updateGlobalCounters(tid, incr, callback) { + function updateCounters(tid, incr, callback) { async.parallel([ function(next) { db.incrObjectFieldBy('global', 'topicCount', incr, next); }, function(next) { - Topics.getPostCount(tid, function(err, postCount) { + Topics.getTopicFields(tid, ['cid', 'postcount'], function(err, topicData) { if (err) { return next(err); } - postCount = parseInt(postCount, 10) + 1; - db.incrObjectFieldBy('global', 'postCount', incr * postCount, next); + var postCountChange = incr * parseInt(topicData.postcount, 10); + async.parallel([ + function(next) { + db.incrObjectFieldBy('global', 'postCount', postCountChange, next); + }, + function(next) { + db.incrObjectFieldBy('category:' + topicData.cid, 'post_count', postCountChange, next); + }, + function(next) { + db.incrObjectFieldBy('category:' + topicData.cid, 'topic_count', incr, next); + } + ], next); }); } ], callback); @@ -38,21 +48,13 @@ module.exports = function(Topics) { }, function(next) { db.sortedSetRemove('topics:views', tid, next); - }, - function(next) { - Topics.getTopicField(tid, 'cid', function(err, cid) { - if(err) { - return next(err); - } - db.incrObjectFieldBy('category:' + cid, 'topic_count', -1, next); - }); } ], function(err) { if (err) { return callback(err); } - updateGlobalCounters(tid, -1, callback); + updateCounters(tid, -1, callback); }); }; @@ -74,21 +76,13 @@ module.exports = function(Topics) { }, function(next) { db.sortedSetAdd('topics:views', topicData.viewcount, tid, next); - }, - function(next) { - Topics.getTopicField(tid, 'cid', function(err, cid) { - if(err) { - return next(err); - } - db.incrObjectFieldBy('category:' + cid, 'topic_count', 1, next); - }); } ], function(err) { if (err) { return callback(err); } - updateGlobalCounters(tid, 1, callback); + updateCounters(tid, 1, callback); }); }); }; diff --git a/src/upgrade.js b/src/upgrade.js index 11fd01d189..1ac54d9597 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -19,7 +19,7 @@ var db = require('./database'), schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema - latestSchema = Date.UTC(2014, 5, 6); + latestSchema = Date.UTC(2014, 5, 17); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -803,6 +803,51 @@ Upgrade.upgrade = function(callback) { winston.info('[2014/6/6] Topic upgrade - skipped'); next(); } + }, + function(next) { + thisSchemaDate = Date.UTC(2014, 5, 17); + + if (schemaDate < thisSchemaDate) { + winston.info('[2014/6/17] Upgrading category post counts...'); + + db.getSortedSetRange('topics:tid', 0, -1, function(err, tids) { + function upgradeTopic(tid, callback) { + + Topics.getTopicFields(tid, ['cid', 'postcount', 'deleted'], function(err, topicData) { + if (err || !topicData) { + return callback(err); + } + + if (parseInt(topicData.deleted, 10) === 1) { + return callback(); + } + + db.incrObjectFieldBy('category:' + topicData.cid, 'post_count', topicData.postcount, callback); + }); + } + + if (err) { + return next(err); + } + + if (!Array.isArray(tids) || !tids.length) { + winston.info('[2014/6/17] Skipping category post upgrade'); + return Upgrade.update(thisSchemaDate, next); + } + + async.each(tids, upgradeTopic, function(err) { + if (err) { + winston.error('[2014/6/17] Error encountered while upgrading category postcounts'); + return next(err); + } + winston.info('[2014/6/17] Category post counts upgraded'); + Upgrade.update(thisSchemaDate, next); + }); + }); + } else { + winston.info('[2014/6/17] Category post count upgrade - skipped'); + next(); + } } // Add new schema updates here // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 22!!!