From 07d54a455c0db519c6e67a3ada61d4c2e494273c Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Tue, 9 Feb 2016 13:22:43 -0800 Subject: [PATCH] Add challengeMap migrations --- common/models/user.json | 10 ++++ server/middleware.json | 3 +- .../migrate-completed-challenges.js | 60 +++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 server/middlewares/migrate-completed-challenges.js diff --git a/common/models/user.json b/common/models/user.json index ad68b5c2fb..4aa16172f0 100644 --- a/common/models/user.json +++ b/common/models/user.json @@ -148,6 +148,16 @@ "default": false, "description": "Campers is full stack certified" }, + "isChallengeMapMigrated": { + "type": "boolean", + "default": false, + "description": "Migrate completedChallenges array to challenge map" + }, + "challengeMap": { + "type": "object", + "default": {}, + "description": "A map by id of all the user completed challenges" + }, "completedChallenges": { "type": [ { diff --git a/server/middleware.json b/server/middleware.json index fbe4b8801d..6968886d90 100644 --- a/server/middleware.json +++ b/server/middleware.json @@ -47,7 +47,8 @@ "./middlewares/express-rx": {}, "./middlewares/jade-helpers": {}, "./middlewares/global-locals": {}, - "./middlewares/revision-helpers": {} + "./middlewares/revision-helpers": {}, + "./middlewares/migrate-completed-challenges": {} }, "routes": { }, diff --git a/server/middlewares/migrate-completed-challenges.js b/server/middlewares/migrate-completed-challenges.js new file mode 100644 index 0000000000..46ab690aa4 --- /dev/null +++ b/server/middlewares/migrate-completed-challenges.js @@ -0,0 +1,60 @@ +import { Observable, Scheduler } from 'rx'; +import debug from 'debug'; + +const log = debug('freecc:migrate'); + +// buildChallengeMap( +// userId: String, +// completedChallenges: Object[], +// User: User +// ) => Observable +function buildChallengeMap(userId, completedChallenges = [], User) { + return Observable.from( + completedChallenges, + null, + null, + Scheduler.default + ) + .reduce((challengeMap, challenge) => { + const id = challenge.id || challenge._id; + challenge = challenge && typeof challenge.toJSON === 'function' ? + challenge.toJSON() : + challenge; + + challengeMap[id] = challenge; + return challengeMap; + }, {}) + .flatMap(challengeMap => { + const updateData = { + '$set': { + challengeMap, + isChallengeMapMigrated: true + } + }; + return Observable.fromNodeCallback(User.updateAll, User)( + { id: userId }, + updateData, + { allowExtendedOperators: true } + ); + }); +} + +export default function migrateCompletedChallenges() { + return ({ user, app }, res, next) => { + const User = app.models.User; + if (!user || user.isChallengeMapMigrated) { + return next(); + } + return buildChallengeMap( + user.id.toString(), + user.completedChallenges, + User + ) + .subscribe( + count => log('documents update', count), + // errors go here + next, + next + ); + }; +}