diff --git a/migrations/20130908_cleanup_derby_corruption.js b/migrations/20130908_cleanup_derby_corruption.js index 604758f39f..ab4e8da806 100644 --- a/migrations/20130908_cleanup_derby_corruption.js +++ b/migrations/20130908_cleanup_derby_corruption.js @@ -6,41 +6,42 @@ db.users.find().forEach(function(user){ // remove corrupt tasks, which will either be null-value or no id - _.reduce(user.tasks, function(m,task,k) { - if (!task || !task.id) return; + user.tasks = _.reduce(user.tasks, function(m,task,k) { + if (!task || !task.id) return m; if (isNaN(+task.value)) task.value = 0; m[k] = task; + return m; }, {}); // fix NaN stats - _.each(doc.stats, function(v, k) { - if (isNaN(+v)) doc.stats[k] = 0; + _.each(user.stats, function(v,k) { + if (!v || isNaN(+v)) user.stats[k] = 0; return true; }); // remove duplicates, restore ghost tasks ['habit', 'daily', 'todo', 'reward'].forEach(function(type) { - var idList = doc[type + "Ids"]; - var taskIds = _.pluck(_.where(tasks, {type: type}), 'id'); + var idList = user[type + "Ids"]; + var taskIds = _.pluck(_.where(user.tasks, {type: type}), 'id'); var union = _.union(idList, taskIds); var preened = _.filter(union, function(id) { return id && _.contains(taskIds, id); }); if (!_.isEqual(idList, preened)) { - doc[type + "Ids"] = preened; - if (!!doc.markModified) { - doc.markModified(type+'Ids'); + user[type + "Ids"] = preened; + if (!!user.markModified) { + user.markModified(type+'Ids'); } } }); // temporarily remove broken eggs. we'll need to write a migration script to grant gems for and remove these instead - if (doc.items && doc.items.eggs) { - doc.items.eggs = _.filter(doc.items.eggs,function(egg){ + if (user.items && user.items.eggs) { + user.items.eggs = _.filter(user.items.eggs,function(egg){ if (_.isString(egg)) { user.balance += 0.75; // give them 3 gems for each broken egg } else { - return true + return true; } }) } diff --git a/src/models/user.js b/src/models/user.js index 2aecdb8f2a..2109fc06d5 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -218,60 +218,38 @@ var UserSchema = new Schema({ strict: true }); -/* +/** Derby requires a strange storage format for somethign called "refLists". Here we hook into loading the data, so we can provide a more "expected" storage format for our various helper methods. Since the attributes are passed by reference, the underlying data will be modified too - so when we save back to the database, it saves it in the way Derby likes. This will go away after the rewrite is complete */ - - -UserSchema.post('init', function(doc) { - /* Fix corrupt values, FIXME we can remove this after off Derby*/ - - if (doc.items && doc.items.eggs) { - doc.items.eggs = _.filter(doc.items.eggs,function(egg){ - return !_.isString(egg); - }) - } - - _.each(doc.tasks, function(task, k) { - if (!task || !task.id) { - return delete doc.tasks[k]; - } - if (isNaN(+task.value)) { - return task.value = 0; - } - }); - _.each(doc.stats, function(v, k) { - if (isNaN(+v)) { - return doc.stats[k] = 0; - } - }); - +function transformTaskLists(doc) { _.each(['habit', 'daily', 'todo', 'reward'], function(type) { // we use _.transform instead of a simple _.where in order to maintain sort-order - doc[type + "s"] = _.transform(doc[type + "Ids"], function(result, tid) { - result.push(doc.tasks[tid]); - }); + doc[type + "s"] = _.reduce(doc[type + "Ids"], function(m, tid) { + m.push(doc.tasks[tid]); + return m; + }, []); }); +} + +UserSchema.post('init', function(doc) { + transformTaskLists(doc); }); -/*UserSchema.virtual('id').get () -> @_id*/ - - UserSchema.methods.toJSON = function() { var doc = this.toObject(); doc.id = doc._id; + transformTaskLists(doc); // we need to also transform for our server-side routes + + // Remove some unecessary data _.each(['habit', 'daily', 'todo', 'reward'], function(type) { - // we use _.transform instead of a simple _.where in order to maintain sort-order - doc["" + type + "s"] = _.transform(doc["" + type + "Ids"], function(result, tid) { - result.push(doc.tasks[tid]); - }); - //delete doc["#{type}Ids"] + delete doc["#{type}Ids"] }); - //delete doc.tasks + delete doc.tasks doc.filters = {}; + return doc; };