"use strict";
var db = require('./database'),
async = require('async'),
winston = require('winston'),
User = require('./user'),
Topics = require('./topics'),
Posts = require('./posts'),
Categories = require('./categories'),
Groups = require('./groups'),
Meta = require('./meta'),
Plugins = require('./plugins'),
Utils = require('../public/src/utils'),
Upgrade = {},
minSchemaDate = Date.UTC(2014, 1, 14, 21, 50), // This value gets updated every new MINOR version
schemaDate, thisSchemaDate,
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
latestSchema = Date.UTC(2014, 1, 22);
Upgrade.check = function(callback) {
db.get('schemaDate', function(err, value) {
if(!value) {
db.set('schemaDate', latestSchema, function(err) {
callback(true);
});
return;
}
if (parseInt(value, 10) >= latestSchema) {
callback(true);
} else {
callback(false);
}
});
};
Upgrade.upgrade = function(callback) {
var updatesMade = false;
winston.info('Beginning database schema update');
async.series([
function(next) {
// Prepare for upgrade & check to make sure the upgrade is possible
db.get('schemaDate', function(err, value) {
if(!value) {
db.set('schemaDate', latestSchema, function(err) {
next();
});
schemaDate = latestSchema;
} else {
schemaDate = parseInt(value, 10);
}
if (schemaDate >= minSchemaDate) {
next();
} else {
next(new Error('upgrade-not-possible'));
}
});
},
function(next) {
thisSchemaDate = Date.UTC(2014, 1, 19, 18, 15);
if (schemaDate < thisSchemaDate) {
updatesMade = true;
db.setObjectField('widgets:home.tpl', 'motd', JSON.stringify([
{
"widget": "html",
"data": {
"html": Meta.config['motd'] || "Welcome to NodeBB, if you are an administrator of this forum visit the Themes ACP to modify and add widgets."
}
}
]), function(err) {
Meta.configs.remove('motd');
Meta.configs.remove('motd_class');
Meta.configs.remove('show_motd');
winston.info('[2014/2/19] Updated MOTD to use the HTML widget.');
next(err);
});
} else {
winston.info('[2014/2/19] Updating MOTD to use the HTML widget - skipped');
next();
}
},
function(next) {
thisSchemaDate = Date.UTC(2014, 1, 20, 15, 30);
if (schemaDate < thisSchemaDate) {
updatesMade = true;
var container = '
';
db.setObjectField('widgets:category.tpl', 'sidebar', JSON.stringify([
{
"widget": "recentreplies",
"data": {
"title": "Recent Replies",
"container": container
}
},
{
"widget": "activeusers",
"data": {
"title": "Active Users",
"container": container
}
},
{
"widget": "moderators",
"data": {
"title": "Moderators",
"container": container
}
}
]), function(err) {
winston.info('[2014/2/20] Adding Recent Replies, Active Users, and Moderator widgets to category sidebar.');
next(err);
});
} else {
winston.info('[2014/2/20] Adding Recent Replies, Active Users, and Moderator widgets to category sidebar - skipped');
next();
}
},
function(next) {
thisSchemaDate = Date.UTC(2014, 1, 20, 16, 15);
if (schemaDate < thisSchemaDate) {
updatesMade = true;
db.setObjectField('widgets:home.tpl', 'footer', JSON.stringify([
{
"widget": "forumstats",
"data": {}
}
]), function(err) {
winston.info('[2014/2/20] Adding Forum Stats Widget to the Homepage Footer.');
next(err);
});
} else {
winston.info('[2014/2/20] Adding Forum Stats Widget to the Homepage Footer - skipped');
next();
}
},
function(next) {
thisSchemaDate = Date.UTC(2014, 1, 20, 19, 45);
if (schemaDate < thisSchemaDate) {
updatesMade = true;
var container = '';
db.setObjectField('widgets:home.tpl', 'sidebar', JSON.stringify([
{
"widget": "html",
"data": {
"html": Meta.config['motd'] || "Welcome to NodeBB, if you are an administrator of this forum visit the Themes ACP to modify and add widgets.",
"container": container,
"title": "MOTD"
}
}
]), function(err) {
winston.info('[2014/2/20] Updating Lavender MOTD');
next(err);
});
} else {
winston.info('[2014/2/20] Updating Lavender MOTD - skipped');
next();
}
},
function(next) {
thisSchemaDate = Date.UTC(2014, 1, 20, 20, 25);
if (schemaDate < thisSchemaDate) {
updatesMade = true;
db.setAdd('plugins:active', 'nodebb-widget-essentials', function(err) {
winston.info('[2014/2/20] Activating NodeBB Essential Widgets');
Plugins.reload(function() {
next(err);
});
});
} else {
winston.info('[2014/2/20] Activating NodeBB Essential Widgets - skipped');
next();
}
},
function(next) {
thisSchemaDate = Date.UTC(2014, 1, 22);
if (schemaDate < thisSchemaDate) {
updatesMade = true;
db.exists('categories:cid', function(err, exists) {
if(err) {
return next(err);
}
if(!exists) {
winston.info('[2014/2/22] Added categories to sorted set - skipped');
return next();
}
db.getListRange('categories:cid', 0, -1, function(err, cids) {
if(err) {
return next(err);
}
if(!Array.isArray(cids)) {
winston.info('[2014/2/22] Add categories to sorted set - skipped (cant find any cids)');
return next();
}
db.rename('categories:cid', 'categories:cid:old', function(err) {
if(err) {
return next(err);
}
async.each(cids, function(cid, next) {
Categories.getCategoryField(cid, 'order', function(err, order) {
if(err) {
return next(err);
}
// If there was no order present, put it at the end
if (!order) {
order = cids.length;
}
db.sortedSetAdd('categories:cid', order, cid, next);
});
}, function(err) {
if(err) {
return next(err);
}
winston.info('[2014/2/22] Added categories to sorted set');
db.delete('categories:cid:old', next);
});
});
});
});
} else {
winston.info('[2014/2/22] Added categories to sorted set - skipped');
next();
}
}
// Add new schema updates here
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 22!!!
], function(err) {
if (!err) {
db.set('schemaDate', thisSchemaDate, function(err) {
if (!err) {
if(updatesMade) {
winston.info('[upgrade] Schema update complete!');
} else {
winston.info('[upgrade] Schema already up to date!');
}
if (callback) {
callback(err);
} else {
process.exit();
}
} else {
winston.error('[upgrade] Could not update NodeBB schema data!');
process.exit();
}
});
} else {
switch(err.message) {
case 'upgrade-not-possible':
winston.error('[upgrade] NodeBB upgrade could not complete, as your database schema is too far out of date.');
winston.error('[upgrade] Please ensure that you did not skip any minor version upgrades.');
winston.error('[upgrade] (e.g. v0.1.x directly to v0.3.x)');
process.exit();
break;
default:
winston.error('[upgrade] Errors were encountered while updating the NodeBB schema: ' + err.message);
process.exit();
break;
}
}
});
};
module.exports = Upgrade;