2013-11-13 12:46:55 -05:00
"use strict" ;
2013-12-06 14:22:31 -05:00
var db = require ( './database' ) ,
2013-08-13 16:00:24 -04:00
async = require ( 'async' ) ,
2013-08-23 13:14:36 -04:00
winston = require ( 'winston' ) ,
2013-12-31 13:02:49 -05:00
User = require ( './user' ) ,
Topics = require ( './topics' ) ,
2014-01-07 17:30:29 -05:00
Posts = require ( './posts' ) ,
2014-02-22 18:56:37 -05:00
Categories = require ( './categories' ) ,
2014-01-13 13:32:49 -05:00
Groups = require ( './groups' ) ,
2014-01-27 12:50:50 -05:00
Meta = require ( './meta' ) ,
Plugins = require ( './plugins' ) ,
2013-12-31 13:02:49 -05:00
Utils = require ( '../public/src/utils' ) ,
2013-11-13 12:46:55 -05:00
Upgrade = { } ,
2014-03-05 19:41:16 -05:00
minSchemaDate = Date . UTC ( 2014 , 1 , 14 , 21 , 50 ) , // This value gets updated every new MINOR version
2014-02-23 16:35:28 -05:00
schemaDate , thisSchemaDate ,
2013-11-13 12:46:55 -05:00
2013-11-26 14:33:18 -05:00
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
2014-03-05 19:33:10 -05:00
latestSchema = Date . UTC ( 2014 , 1 , 22 ) ;
2013-11-13 12:46:55 -05:00
2014-02-23 16:35:28 -05:00
Upgrade . check = function ( callback ) {
2013-12-06 14:22:31 -05:00
db . get ( 'schemaDate' , function ( err , value ) {
2014-02-23 16:19:30 -05:00
if ( ! value ) {
db . set ( 'schemaDate' , latestSchema , function ( err ) {
callback ( true ) ;
} ) ;
return ;
}
2013-11-13 13:31:36 -05:00
if ( parseInt ( value , 10 ) >= latestSchema ) {
2013-11-13 12:46:55 -05:00
callback ( true ) ;
} else {
callback ( false ) ;
}
} ) ;
} ;
2013-10-03 22:36:00 -04:00
2014-03-05 19:51:16 -05:00
Upgrade . update = function ( schemaDate , callback ) {
db . set ( 'schemaDate' , schemaDate , callback ) ;
} ;
2013-11-21 17:41:27 -05:00
Upgrade . upgrade = function ( callback ) {
2013-12-31 13:02:49 -05:00
var updatesMade = false ;
2013-12-06 14:22:31 -05:00
2013-12-31 13:02:49 -05:00
winston . info ( 'Beginning database schema update' ) ;
2013-10-03 22:36:00 -04:00
async . series ( [
function ( next ) {
2014-01-19 18:34:11 -05:00
// Prepare for upgrade & check to make sure the upgrade is possible
2013-12-31 13:02:49 -05:00
db . get ( 'schemaDate' , function ( err , value ) {
2014-02-23 16:35:28 -05:00
if ( ! value ) {
db . set ( 'schemaDate' , latestSchema , function ( err ) {
next ( ) ;
} ) ;
schemaDate = latestSchema ;
} else {
schemaDate = parseInt ( value , 10 ) ;
}
2014-01-03 20:20:23 -05:00
2014-02-23 16:35:28 -05:00
if ( schemaDate >= minSchemaDate ) {
2014-01-03 20:20:23 -05:00
next ( ) ;
2014-01-19 18:34:11 -05:00
} else {
next ( new Error ( 'upgrade-not-possible' ) ) ;
}
} ) ;
2014-01-04 01:15:41 -05:00
} ,
2014-02-19 18:13:56 -05:00
function ( next ) {
2014-03-05 19:33:10 -05:00
thisSchemaDate = Date . UTC ( 2014 , 1 , 19 , 18 , 15 ) ;
2014-02-19 18:13:56 -05:00
if ( schemaDate < thisSchemaDate ) {
2014-02-20 19:48:08 -05:00
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 <a target='_blank' href='/admin/themes'>Themes</a> ACP to modify and add widgets."
2014-02-19 18:13:56 -05:00
}
2014-02-20 19:48:08 -05:00
}
] ) , function ( err ) {
Meta . configs . remove ( 'motd' ) ;
Meta . configs . remove ( 'motd_class' ) ;
Meta . configs . remove ( 'show_motd' ) ;
2014-02-19 18:13:56 -05:00
2014-02-20 19:48:08 -05:00
winston . info ( '[2014/2/19] Updated MOTD to use the HTML widget.' ) ;
2014-03-05 19:51:16 -05:00
if ( err ) {
next ( err ) ;
} else {
Upgrade . update ( thisSchemaDate , next ) ;
}
2014-02-20 19:48:08 -05:00
} ) ;
2014-02-19 18:13:56 -05:00
} else {
winston . info ( '[2014/2/19] Updating MOTD to use the HTML widget - skipped' ) ;
next ( ) ;
}
2014-02-20 15:28:37 -05:00
} ,
function ( next ) {
2014-03-05 19:33:10 -05:00
thisSchemaDate = Date . UTC ( 2014 , 1 , 20 , 15 , 30 ) ;
2014-02-20 15:28:37 -05:00
if ( schemaDate < thisSchemaDate ) {
2014-02-20 18:45:38 -05:00
var container = '<div class="panel panel-default"><div class="panel-heading">{title}</div><div class="panel-body">{body}</div></div>' ;
2014-02-22 18:56:37 -05:00
2014-02-20 15:28:37 -05:00
db . setObjectField ( 'widgets:category.tpl' , 'sidebar' , JSON . stringify ( [
{
"widget" : "recentreplies" ,
2014-02-20 18:45:38 -05:00
"data" : {
"title" : "Recent Replies" ,
"container" : container
}
2014-02-20 15:28:37 -05:00
} ,
{
"widget" : "activeusers" ,
2014-02-20 18:45:38 -05:00
"data" : {
"title" : "Active Users" ,
"container" : container
}
2014-02-20 15:28:37 -05:00
} ,
{
"widget" : "moderators" ,
2014-02-20 18:45:38 -05:00
"data" : {
"title" : "Moderators" ,
"container" : container
}
2014-02-20 15:28:37 -05:00
}
] ) , function ( err ) {
2014-02-20 15:31:42 -05:00
winston . info ( '[2014/2/20] Adding Recent Replies, Active Users, and Moderator widgets to category sidebar.' ) ;
2014-03-05 19:51:16 -05:00
if ( err ) {
next ( err ) ;
} else {
Upgrade . update ( thisSchemaDate , next ) ;
}
2014-02-20 15:28:37 -05:00
} ) ;
} else {
2014-02-20 15:31:42 -05:00
winston . info ( '[2014/2/20] Adding Recent Replies, Active Users, and Moderator widgets to category sidebar - skipped' ) ;
2014-02-20 15:28:37 -05:00
next ( ) ;
}
2014-02-20 16:14:24 -05:00
} ,
function ( next ) {
2014-03-05 19:33:10 -05:00
thisSchemaDate = Date . UTC ( 2014 , 1 , 20 , 16 , 15 ) ;
2014-02-20 16:14:24 -05:00
if ( schemaDate < thisSchemaDate ) {
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.' ) ;
2014-03-05 19:51:16 -05:00
if ( err ) {
next ( err ) ;
} else {
Upgrade . update ( thisSchemaDate , next ) ;
}
2014-02-20 16:14:24 -05:00
} ) ;
} else {
winston . info ( '[2014/2/20] Adding Forum Stats Widget to the Homepage Footer - skipped' ) ;
next ( ) ;
}
2014-02-20 19:48:08 -05:00
} ,
function ( next ) {
2014-03-05 19:33:10 -05:00
thisSchemaDate = Date . UTC ( 2014 , 1 , 20 , 19 , 45 ) ;
2014-02-20 19:48:08 -05:00
if ( schemaDate < thisSchemaDate ) {
var container = '<div class="panel panel-default"><div class="panel-heading">{title}</div><div class="panel-body">{body}</div></div>' ;
2014-02-22 18:56:37 -05:00
2014-02-20 19:48:08 -05:00
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 <a target='_blank' href='/admin/themes'>Themes</a> ACP to modify and add widgets." ,
"container" : container ,
"title" : "MOTD"
}
}
] ) , function ( err ) {
winston . info ( '[2014/2/20] Updating Lavender MOTD' ) ;
2014-03-05 19:51:16 -05:00
if ( err ) {
next ( err ) ;
} else {
Upgrade . update ( thisSchemaDate , next ) ;
}
2014-02-20 19:48:08 -05:00
} ) ;
} else {
winston . info ( '[2014/2/20] Updating Lavender MOTD - skipped' ) ;
next ( ) ;
}
2014-02-20 20:23:30 -05:00
} ,
function ( next ) {
2014-03-05 19:33:10 -05:00
thisSchemaDate = Date . UTC ( 2014 , 1 , 20 , 20 , 25 ) ;
2014-02-20 20:23:30 -05:00
if ( schemaDate < thisSchemaDate ) {
db . setAdd ( 'plugins:active' , 'nodebb-widget-essentials' , function ( err ) {
winston . info ( '[2014/2/20] Activating NodeBB Essential Widgets' ) ;
2014-02-20 20:33:37 -05:00
Plugins . reload ( function ( ) {
2014-03-05 21:19:36 -05:00
if ( err ) {
next ( err ) ;
} else {
Upgrade . update ( thisSchemaDate , next ) ;
}
2014-02-20 20:33:37 -05:00
} ) ;
2014-02-20 20:23:30 -05:00
} ) ;
} else {
winston . info ( '[2014/2/20] Activating NodeBB Essential Widgets - skipped' ) ;
2014-03-05 21:19:36 -05:00
next ( ) ;
2014-02-20 20:23:30 -05:00
}
2014-02-22 18:56:37 -05:00
} ,
function ( next ) {
2014-03-05 19:33:10 -05:00
thisSchemaDate = Date . UTC ( 2014 , 1 , 22 ) ;
2014-02-22 18:56:37 -05:00
if ( schemaDate < thisSchemaDate ) {
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 ) {
2014-03-06 19:48:38 -05:00
// Naive type-checking, becaue DBAL does not have .type() support
2014-02-22 18:56:37 -05:00
if ( err ) {
2014-03-06 19:48:38 -05:00
// Most likely upgraded already. Skip.
winston . info ( '[2014/2/22] Added categories to sorted set - skipped' ) ;
return Upgrade . update ( thisSchemaDate , next ) ;
2014-02-22 18:56:37 -05:00
}
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 ) ;
}
2014-03-03 10:17:11 -05:00
// If there was no order present, put it at the end
if ( ! order ) {
order = cids . length ;
}
2014-02-22 18:56:37 -05:00
db . sortedSetAdd ( 'categories:cid' , order , cid , next ) ;
} ) ;
} , function ( err ) {
if ( err ) {
return next ( err ) ;
}
winston . info ( '[2014/2/22] Added categories to sorted set' ) ;
2014-03-05 19:51:16 -05:00
db . delete ( 'categories:cid:old' ) ;
Upgrade . update ( thisSchemaDate , next ) ;
2014-02-22 18:56:37 -05:00
} ) ;
} ) ;
} ) ;
} ) ;
} else {
winston . info ( '[2014/2/22] Added categories to sorted set - skipped' ) ;
next ( ) ;
}
2014-02-14 14:39:32 -05:00
}
2013-10-03 22:36:00 -04:00
// Add new schema updates here
2014-02-23 16:35:28 -05:00
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 22!!!
2013-12-06 14:22:31 -05:00
] , function ( err ) {
if ( ! err ) {
db . set ( 'schemaDate' , thisSchemaDate , function ( err ) {
if ( ! err ) {
2013-12-11 22:50:36 -05:00
if ( updatesMade ) {
2013-12-31 13:02:49 -05:00
winston . info ( '[upgrade] Schema update complete!' ) ;
2013-12-11 22:50:36 -05:00
} else {
2013-12-31 13:02:49 -05:00
winston . info ( '[upgrade] Schema already up to date!' ) ;
2013-12-11 22:50:36 -05:00
}
2014-02-23 16:35:28 -05:00
2013-12-06 14:22:31 -05:00
if ( callback ) {
callback ( err ) ;
} else {
process . exit ( ) ;
}
} else {
2013-12-31 13:02:49 -05:00
winston . error ( '[upgrade] Could not update NodeBB schema data!' ) ;
2013-12-06 14:22:31 -05:00
process . exit ( ) ;
}
} ) ;
} else {
2014-01-19 18:34:11 -05:00
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 ;
}
2013-12-06 14:22:31 -05:00
}
} ) ;
2013-12-31 13:02:49 -05:00
} ;
2013-12-06 14:22:31 -05:00
2013-10-03 22:36:00 -04:00
module . exports = Upgrade ;