diff --git a/app.js b/app.js index 2a4fb645ec..896dd82750 100644 --- a/app.js +++ b/app.js @@ -88,30 +88,41 @@ websockets = require('./src/websockets.js'), posts = require('./src/posts.js'), plugins = require('./src/plugins'), // Don't remove this - plugins initializes itself - Notifications = require('./src/notifications'); + Notifications = require('./src/notifications'), + Upgrade = require('./src/upgrade'); - websockets.init(SocketIO); + Upgrade.check(function(schema_ok) { + if (schema_ok || nconf.get('check-schema') === false) { + websockets.init(SocketIO); - global.templates = {}; - global.translator = translator; + global.templates = {}; + global.translator = translator; - translator.loadServer(); - - var customTemplates = meta.config['theme:templates'] ? path.join(__dirname, 'node_modules', meta.config['theme:id'], meta.config['theme:templates']) : false; + translator.loadServer(); - // todo: replace below with read directory code, derp. - templates.init([ - 'header', 'footer', 'logout', 'outgoing', 'admin/header', 'admin/footer', 'admin/index', - 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext', - 'emails/header', 'emails/footer', + var customTemplates = meta.config['theme:templates'] ? path.join(__dirname, 'node_modules', meta.config['theme:id'], meta.config['theme:templates']) : false; - 'noscript/header', 'noscript/home', 'noscript/category', 'noscript/topic' - ], customTemplates); - + // todo: replace below with read directory code, derp. + templates.init([ + 'header', 'footer', 'logout', 'outgoing', 'admin/header', 'admin/footer', 'admin/index', + 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext', + 'emails/header', 'emails/footer', - templates.ready(webserver.init); + 'noscript/header', 'noscript/home', 'noscript/category', 'noscript/topic' + ], customTemplates); - Notifications.init(); + + templates.ready(webserver.init); + + Notifications.init(); + } else { + winston.warn('Your NodeBB schema is out-of-date. Please run the following command to bring your dataset up to spec:'); + winston.warn(' node app --upgrade'); + winston.warn('To ignore this error (not recommended):'); + winston.warn(' node app --no-check-schema') + process.exit(); + } + }); }); } else if (nconf.get('setup') || !fs.existsSync(__dirname + '/config.json')) { // New install, ask setup questions diff --git a/src/upgrade.js b/src/upgrade.js index f4040a5886..5dcdbabda3 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -1,110 +1,139 @@ +"use strict"; + var RDB = require('./redis.js'), async = require('async'), winston = require('winston'), - notifications = require('./notifications') - Upgrade = {}; + notifications = require('./notifications'), + Upgrade = {}, + + schemaDate, thisSchemaDate; + +Upgrade.check = function(callback) { + var latestSchema = new Date(2013, 10, 11).getTime(); + + RDB.get('schemaDate', function(err, value) { + if (parseInt(value, 10) > latestSchema) { + callback(true); + } else { + callback(false); + } + }); +}; Upgrade.upgrade = function() { winston.info('Beginning Redis database schema update'); async.series([ function(next) { - RDB.hget('notifications:1', 'score', function(err, score) { - if (score) { - async.series([ - function(next) { - RDB.keys('uid:*:notifications:flag', function(err, keys) { - if (keys.length > 0) { - winston.info('[2013/10/03] Removing deprecated Notification Flags'); - async.each(keys, function(key, next) { - RDB.del(key, next); - }, next); - } else { - winston.info('[2013/10/03] No Notification Flags found. Good.'); - next(); - } - }); - }, - function(next) { - winston.info('[2013/10/03] Updating Notifications'); - RDB.keys('uid:*:notifications:*', function(err, keys) { - async.each(keys, function(key, next) { - RDB.zrange(key, 0, -1, function(err, nids) { - async.each(nids, function(nid, next) { - notifications.get(nid, null, function(notif_data) { - RDB.zadd(key, notif_data.datetime, nid, next); - }); - }, next); - }); - }, next); - }); - }, - function(next) { - RDB.keys('notifications:*', function(err, keys) { - if (keys.length > 0) { - winston.info('[2013/10/03] Removing Notification Scores'); - async.each(keys, function(key, next) { - if (key === 'notifications:next_nid') return next(); - RDB.hdel(key, 'score', next); - }, next); - } else { - winston.info('[2013/10/03] No Notification Scores found. Good.'); - next(); - } - }); - } - ], next); - } else { - winston.info('[2013/10/03] Updates to Notifications skipped.'); - next(); - } + RDB.get('schemaDate', function(err, value) { + schemaDate = value; + next(); }); }, function(next) { - RDB.exists('notifications', function(err, exists) { - if (!exists) { - RDB.keys('notifications:*', function(err, keys) { - var multi = RDB.multi(); + thisSchemaDate = new Date(2013, 9, 3).getTime(); + if (schemaDate < thisSchemaDate) { + async.series([ + function(next) { + RDB.keys('uid:*:notifications:flag', function(err, keys) { + if (keys.length > 0) { + winston.info('[2013/10/03] Removing deprecated Notification Flags'); + async.each(keys, function(key, next) { + RDB.del(key, next); + }, next); + } else { + winston.info('[2013/10/03] No Notification Flags found. Good.'); + next(); + } + }); + }, + function(next) { + winston.info('[2013/10/03] Updating Notifications'); + RDB.keys('uid:*:notifications:*', function(err, keys) { + async.each(keys, function(key, next) { + RDB.zrange(key, 0, -1, function(err, nids) { + async.each(nids, function(nid, next) { + notifications.get(nid, null, function(notif_data) { + RDB.zadd(key, notif_data.datetime, nid, next); + }); + }, next); + }); + }, next); + }); + }, + function(next) { + RDB.keys('notifications:*', function(err, keys) { + if (keys.length > 0) { + winston.info('[2013/10/03] Removing Notification Scores'); + async.each(keys, function(key, next) { + if (key === 'notifications:next_nid') { + return next(); + } - keys = keys.filter(function(key) { - if (key === 'notifications:next_nid') { - return false; + RDB.hdel(key, 'score', next); + }, next); } else { - return true; + winston.info('[2013/10/03] No Notification Scores found. Good.'); + next(); } - }).map(function(key) { - return key.slice(14); }); + } + ], next); + } else { + winston.info('[2013/10/03] Updates to Notifications skipped.'); + next(); + } + }, + function(next) { + thisSchemaDate = new Date(2013, 9, 23).getTime(); + if (schemaDate < thisSchemaDate) { + RDB.keys('notifications:*', function(err, keys) { + var multi = RDB.multi(); - winston.info('[2013/10/23] Adding existing notifications to set'); - RDB.sadd('notifications', keys, next); + keys = keys.filter(function(key) { + if (key === 'notifications:next_nid') { + return false; + } else { + return true; + } + }).map(function(key) { + return key.slice(14); }); - } else { - winston.info('[2013/10/23] Updates to Notifications skipped.'); - next(); - } - }); + + winston.info('[2013/10/23] Adding existing notifications to set'); + RDB.sadd('notifications', keys, next); + }); + } else { + winston.info('[2013/10/23] Updates to Notifications skipped.'); + next(); + } }, function(next) { - RDB.hget('config', 'postDelay', function(err, postDelay) { - if(parseInt(postDelay, 10) > 150) { - RDB.hset('config', 'postDelay', 10, function(err, success) { - winston.info('[2013/11/11] Updated postDelay to 10 seconds.'); - next(); - }); - } else { - winston.info('[2013/11/11] Update to postDelay skipped.'); + thisSchemaDate = new Date(2013, 10, 11).getTime(); + if (schemaDate < thisSchemaDate) { + RDB.hset('config', 'postDelay', 10, function(err, success) { + winston.info('[2013/11/11] Updated postDelay to 10 seconds.'); next(); - } - }); + }); + } else { + winston.info('[2013/11/11] Update to postDelay skipped.'); + next(); + } } // Add new schema updates here + // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 12!!! ], function(err) { if (!err) { - winston.info('Redis schema update complete!'); - process.exit(); + RDB.set('schemaDate', thisSchemaDate, function(err) { + if (!err) { + winston.info('[upgrade] Redis schema update complete!'); + process.exit(); + } else { + winston.error('[upgrade] Could not update NodeBB schema date!'); + } + }); } else { - winston.error('Errors were encountered while updating the NodeBB schema: ' + err.message); + winston.error('[upgrade] Errors were encountered while updating the NodeBB schema: ' + err.message); } }); };