Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit f269186

Browse files
committed
Merge pull request #171 from hesibo/master
Get Marathon Match Challenge Reg Info API
2 parents 4f25f08 + 6753740 commit f269186

17 files changed

+888
-29
lines changed

actions/marathonChallenges.js

Lines changed: 161 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
/*
22
* Copyright (C) 2013 - 2014 TopCoder Inc., All Rights Reserved.
33
*
4-
* @version 1.3
5-
* @author Sky_, TCSASSEMBLER, freegod, Ghost_141
4+
* @version 1.4
5+
* @author Sky_, TCSASSEMBLER, freegod, Ghost_141, hesibo
66
* changes in 1.1:
77
* - implement marathon API
88
* changes in 1.2:
99
* - Use empty result set instead of 404 error in get marathon challenges API.
1010
* Changes in 1.3:
1111
* - Implement the register marathon match challenge API.
12+
* changes in 1.4:
13+
* - Implement the get marathon match challenge register info API
14+
* - refactor register marathon match challenge API
1215
*/
1316
"use strict";
1417
var async = require('async');
@@ -104,8 +107,8 @@ function setDateToParams(helper, sqlParams, dateInterval, inputCodePrefix) {
104107
}
105108

106109
/**
107-
* The API for searching Marathon challenges
108-
*/
110+
* The API for searching Marathon challenges
111+
*/
109112
exports.searchMarathonChallenges = {
110113
name: "searchMarathonChallenges",
111114
description: "searchMarathonChallenges",
@@ -294,7 +297,7 @@ exports.searchMarathonChallenges = {
294297

295298
/**
296299
* Compute progressResources field for challenge details
297-
*
300+
*
298301
* @param {Array<Object>} submissions - the submissions. Result of detail_progress_XXX query.
299302
* @param {Array<Object>} registrants - the registrants. Result of detail_progress_XXX_registrants query.
300303
* @param {Array<Object>} competitors - the competitors. Result of detail_progress_competitors query.
@@ -398,8 +401,8 @@ function computeProgressResources(submissions, registrants, competitors, interva
398401
}
399402

400403
/**
401-
* The API for getting Marathon challenge
402-
*/
404+
* The API for getting Marathon challenge
405+
*/
403406
exports.getMarathonChallenge = {
404407
name: "getMarathonChallenge",
405408
description: "getMarathonChallenge",
@@ -515,35 +518,36 @@ exports.getMarathonChallenge = {
515518
});
516519
}
517520
};
518-
519521
/**
520-
* Register the marathon match challenge.
521-
* @param {Object} api - the api object.
522-
* @param {Object} connection - the connection object.
523-
* @param {Function} next - the callback function.
524-
* @since 1.3
522+
* perform checking before register marathon or view register info
523+
*
524+
* @param {Object} api - the api object
525+
* @param {Boolean} isRegister - it is register marathon or not
526+
* @param {Object} connection - the connection object
527+
* @param {Object} sqlParams - the sql parameters object
528+
* @param {Function} callback - the callback function
529+
*
530+
* @since 1.4
525531
*/
526-
function registerMarathonMatchChallenge(api, connection, next) {
527-
var helper = api.helper, dbConnectionMap = connection.dbConnectionMap, roundId, sqlParams, isHighSchool,
532+
function preRegisterMarathonCheck(api, isRegister, connection, sqlParams, callback) {
533+
var dbConnectionMap = connection.dbConnectionMap,
534+
roundId = Number(decodeURI(connection.params.roundId).trim()),
528535
execQuery = function (name) {
529536
return function (cb) {
530537
api.dataAccess.executeQuery(name, sqlParams, dbConnectionMap, cb);
531538
};
532-
}, caller = connection.caller;
533-
roundId = Number(decodeURI(connection.params.roundId).trim());
539+
};
534540
async.waterfall([
535541
function (cb) {
536-
var error = helper.checkPositiveInteger(roundId, 'roundId') ||
537-
helper.checkMaxInt(roundId, 'roundId') ||
538-
helper.checkMember(connection, 'Authorization information needed or incorrect.');
542+
var error = api.helper.checkPositiveInteger(roundId, 'roundId') ||
543+
api.helper.checkMaxInt(roundId, 'roundId') ||
544+
api.helper.checkMember(connection, 'Authorization information needed or incorrect.');
539545
if (error) {
540546
cb(error);
541547
return;
542548
}
543-
sqlParams = {
544-
round_id: roundId,
545-
user_id: caller.userId
546-
};
549+
sqlParams.round_id = roundId;
550+
sqlParams.user_id = connection.caller.userId;
547551
// check
548552
async.parallel({
549553
checkResult: execQuery('check_marathon_challenge_register'),
@@ -588,7 +592,7 @@ function registerMarathonMatchChallenge(api, connection, next) {
588592
}
589593
}
590594
// If the caller has already reigstered for this challenge.
591-
if (checkResult.is_round_registered) {
595+
if (isRegister && checkResult.is_round_registered) {
592596
cb(new BadRequestError('You already registered for this challenge.'));
593597
return;
594598
}
@@ -619,18 +623,47 @@ function registerMarathonMatchChallenge(api, connection, next) {
619623
cb(new BadRequestError('There are no more spots available for the round.'));
620624
return;
621625
}
626+
cb(null, checkResult);
627+
}
628+
], function (err, checkResult) {
629+
if (isRegister) {
630+
callback(err, checkResult);
631+
} else {
632+
callback(err);
633+
}
634+
});
635+
}
622636

637+
/**
638+
* Register the marathon match challenge.
639+
* @param {Object} api - the api object.
640+
* @param {Object} connection - the connection object.
641+
* @param {Function} next - the callback function.
642+
* @since 1.3
643+
*/
644+
function registerMarathonMatchChallenge(api, connection, next) {
645+
var sqlParams = {},
646+
execQuery = function (name) {
647+
return function (cb) {
648+
api.dataAccess.executeQuery(name, sqlParams, connection.dbConnectionMap, cb);
649+
};
650+
};
651+
async.waterfall([
652+
function (cb) {
653+
preRegisterMarathonCheck(api, true, connection, sqlParams, cb);
654+
},
655+
function (checkResult, cb) {
623656
_.extend(sqlParams, {
624657
eligible: 1,
625-
userId: caller.userId,
658+
userId: connection.caller.userId,
626659
attended: 'N'
627660
});
628661
async.parallel({
629662
roundRegistration: execQuery('insert_round_registration'),
630663
roundTerms: execQuery('insert_round_terms_acceptance'),
631664
algoRating: function (cbx) {
632665
if (!checkResult.is_rated) {
633-
api.dataAccess.executeQuery('add_algo_rating', sqlParams, dbConnectionMap, cbx);
666+
api.dataAccess.executeQuery('add_algo_rating', sqlParams, connection.dbConnectionMap, cbx);
634667
return;
635668
}
636669
cbx();
@@ -642,7 +675,7 @@ function registerMarathonMatchChallenge(api, connection, next) {
642675
}
643676
], function (err) {
644677
if (err) {
645-
helper.handleError(api, connection, err);
678+
api.helper.handleError(api, connection, err);
646679
} else {
647680
connection.response = { success: true };
648681
}
@@ -677,3 +710,103 @@ exports.registerMarathonChallenge = {
677710
}
678711
}
679712
};
713+
714+
/**
715+
* Get marathon match challenge register information.
716+
*
717+
* @param {Object} api - the api object.
718+
* @param {Object} connection - the connection object.
719+
* @param {Function} next - the callback function.
720+
*
721+
* @since 1.4
722+
*/
723+
function getMarathonChallengeRegInfo(api, connection, next) {
724+
var sqlParams = {}, result = {}, questionIdMapping = {}, index = 0;
725+
async.waterfall([
726+
function (cb) {
727+
preRegisterMarathonCheck(api, false, connection, sqlParams, cb);
728+
},
729+
function (cb) {
730+
api.dataAccess.executeQuery('get_marathon_round_term', sqlParams, connection.dbConnectionMap, cb);
731+
},
732+
function (term, cb) {
733+
if (term.length === 0) {
734+
cb(new NotFoundError('Could not find specified round terms.'));
735+
return;
736+
}
737+
result.term = {
738+
contestName: term[0].contest_name,
739+
roundName: term[0].round_name,
740+
termsContent: term[0].terms_content || ''
741+
};
742+
api.dataAccess.executeQuery('get_marathon_round_questions', sqlParams, connection.dbConnectionMap, cb);
743+
},
744+
function (questions, cb) {
745+
sqlParams.question_ids = [];
746+
result.questions = _.map(questions, function (question) {
747+
sqlParams.question_ids.push(question.question_id);
748+
questionIdMapping[question.question_id] = index;
749+
index = index + 1;
750+
return {
751+
id: question.question_id,
752+
style: question.style,
753+
type: question.type,
754+
text: question.text,
755+
answers: []
756+
};
757+
});
758+
if (!_.isEmpty(sqlParams.question_ids)) {
759+
api.dataAccess.executeQuery('get_marathon_round_question_answers', sqlParams, connection.dbConnectionMap, cb);
760+
} else {
761+
cb(null, null);
762+
}
763+
},
764+
function (answers, cb) {
765+
if (!_.isEmpty(sqlParams.question_ids)) {
766+
answers.forEach(function (answer) {
767+
result.questions[questionIdMapping[answer.question_id]].answers.push({
768+
id: answer.answer_id,
769+
text: answer.text,
770+
sortOrder: answer.sort_order || -1,
771+
correct: answer.correct === 0 ? false : true
772+
});
773+
});
774+
}
775+
cb();
776+
}
777+
], function (err) {
778+
if (err) {
779+
api.helper.handleError(api, connection, err);
780+
} else {
781+
connection.response = result;
782+
}
783+
next(connection, true);
784+
});
785+
}
786+
787+
/**
788+
* The API for get marathon match challenge register information.
789+
*
790+
* @since 1.4
791+
*/
792+
exports.getMarathonChallengeRegInfo = {
793+
name: 'getMarathonChallengeRegInfo',
794+
description: 'get marathon match challenge register information',
795+
inputs: {
796+
required: ['roundId'],
797+
optional: []
798+
},
799+
blockedConnectionTypes: [],
800+
outputExample: {},
801+
version: 'v2',
802+
transaction: 'read', // this action is read-only
803+
databases: ['informixoltp', 'common_oltp'],
804+
run: function (api, connection, next) {
805+
if (!connection.dbConnectionMap) {
806+
api.helper.handleNoConnection(api, connection, next);
807+
} else {
808+
api.log('Execute getMarathonChallengeRegInfo#run', 'debug');
809+
getMarathonChallengeRegInfo(api, connection, next);
810+
}
811+
}
812+
};

0 commit comments

Comments
 (0)