11/*
22 * Copyright (C) 2014 TopCoder Inc., All Rights Reserved.
33 *
4- * @version 1.2
4+ * @version 1.3
55 * @author muzehyun, Ghost_141
66 * Changes in 1.1:
77 * - Implement user activation email api.
88 * Changes in 1.2:
99 * - Implement get user identity api.
10+ * Changes in 1.3:
11+ * - Implement get user algorithm challenges api.
1012 */
1113'use strict' ;
1214var async = require ( 'async' ) ;
@@ -29,6 +31,13 @@ var activationEmailSubject = "Topcoder User Registration Activation";
2931 */
3032var activationEmailSenderName = "Topcoder API" ;
3133
34+ /**
35+ * The valid sort column values for get user algo challenges api.
36+ * @since 1.3
37+ */
38+ var VALID_SORT_COLUMN_ALGO_CHALLENGES = [ 'id' , 'type' , 'codingDuration' , 'placement' , 'numContestants' ,
39+ 'numSubmitters' ] ;
40+
3241/**
3342 * It validates activation code and retrieves user id from activation code
3443 * @param {String } activationCode - activation code string
@@ -332,7 +341,7 @@ exports.getUserIdentity = {
332341 * @since 1.2
333342 */
334343function getUserIdentityByAuth0Id ( api , connection , next ) {
335- var helper = api . helper ,
344+ var helper = api . helper ,
336345 auth0id = connection . params . id ,
337346 userid = 0 ,
338347 dbConnectionMap = connection . dbConnectionMap ,
@@ -343,35 +352,34 @@ function getUserIdentityByAuth0Id(api, connection, next) {
343352 function ( cb ) {
344353 try {
345354 var splits = auth0id . split ( '|' ) ;
346- if ( splits [ 0 ] == 'ad' ) {
355+ if ( splits [ 0 ] === 'ad' ) {
347356 cb ( null , [ { user_id : Number ( splits [ 1 ] ) } ] ) ;
348357 } else {
349- api . helper . getProviderId ( splits [ 0 ] , function ( err , provider ) {
358+ api . helper . getProviderId ( splits [ 0 ] , function ( err , provider ) {
350359 if ( err ) {
351360 cb ( notfound ) ;
352361 } else {
353362 api . dataAccess . executeQuery ( "get_user_by_social_login" ,
354- {
355- social_user_id : splits [ 1 ] ,
356- provider_id : provider
357- } ,
358- dbConnectionMap , cb ) ;
363+ {
364+ social_user_id : splits [ 1 ] ,
365+ provider_id : provider
366+ } ,
367+ dbConnectionMap , cb ) ;
359368 }
360369 } ) ;
361370 }
362- }
363- catch ( exc ) {
371+ } catch ( exc ) {
364372 cb ( notfound ) ;
365373 }
366374 } ,
367375 function ( result , cb ) {
368376 if ( ! result [ 0 ] ) {
369377 cb ( notfound ) ;
370378 } else {
371- userid = result [ 0 ] . user_id
372- api . dataAccess . executeQuery ( 'get_user_email_and_handle' ,
373- { userId : userid } ,
374- dbConnectionMap , cb ) ;
379+ userid = result [ 0 ] . user_id ;
380+ api . dataAccess . executeQuery ( 'get_user_email_and_handle' ,
381+ { userId : userid } ,
382+ dbConnectionMap , cb ) ;
375383 }
376384 } ,
377385 function ( rs , cb ) {
@@ -422,3 +430,136 @@ exports.getUserIdentityByAuth0Id = {
422430 }
423431 }
424432} ;
433+
434+ /**
435+ * Handle the get algorithm challenges that user participated to.
436+ * @param {Object } api - The api object.
437+ * @param {Object } connection - The connection object.
438+ * @param {Function } next - The callback function.
439+ * @since 1.3
440+ */
441+ function getUserAlgorithmChallenges ( api , connection , next ) {
442+ var helper = api . helper , dbConnectionMap = connection . dbConnectionMap , response , sqlParams , sortOrder , sortColumn ,
443+ exeQuery = function ( name ) {
444+ return function ( cbx ) {
445+ api . dataAccess . executeQuery ( name , sqlParams , dbConnectionMap , cbx ) ;
446+ } ;
447+ } ,
448+ handle = connection . params . handle ,
449+ pageIndex = Number ( connection . params . pageIndex || 1 ) ,
450+ pageSize = Number ( connection . params . pageSize || 10 ) ;
451+
452+ // If the sortOrder is set and sortColumn is missing.
453+ if ( connection . params . sortOrder && ! connection . params . sortColumn ) {
454+ helper . handleError ( api , connection , new BadRequestError ( 'The sortColumn is missing.' ) ) ;
455+ next ( connection , true ) ;
456+ return ;
457+ }
458+
459+ sortOrder = ( connection . params . sortOrder || "asc" ) . toLowerCase ( ) ;
460+ sortColumn = connection . params . sortColumn || "id" ;
461+
462+ if ( pageIndex === - 1 ) {
463+ pageSize = helper . MAX_INT ;
464+ pageIndex = 1 ;
465+ }
466+
467+ if ( sortColumn . toLowerCase ( ) === 'placement' ) {
468+ //reverse the sortOrder value because for placement 1 is the best so the descending order should be like 1, 2, 3.
469+ sortOrder = sortOrder === 'asc' ? 'desc' : 'asc' ;
470+ }
471+
472+ async . waterfall ( [
473+ function ( cb ) {
474+ var error = helper . checkPageIndex ( pageIndex , "pageIndex" )
475+ || helper . checkStringParameter ( handle , "handle" , 30 )
476+ || helper . checkPositiveInteger ( pageSize , "pageSize" )
477+ || helper . checkMaxInt ( pageSize , "pageSize" )
478+ || helper . checkContains ( [ 'asc' , 'desc' ] , sortOrder , "sortOrder" )
479+ || helper . checkSortColumn ( VALID_SORT_COLUMN_ALGO_CHALLENGES , sortColumn . toLowerCase ( ) ) ;
480+ cb ( error ) ;
481+ } ,
482+ function ( cb ) {
483+ helper . checkUserExists ( handle , api , dbConnectionMap , cb ) ;
484+ } ,
485+ function ( err , cb ) {
486+ if ( err ) {
487+ cb ( err ) ;
488+ return ;
489+ }
490+ helper . checkUserActivated ( handle , api , dbConnectionMap , cb ) ;
491+ } ,
492+ function ( err , cb ) {
493+ if ( err ) {
494+ cb ( err ) ;
495+ return ;
496+ }
497+ sqlParams = {
498+ first_row_index : ( pageIndex - 1 ) * pageSize ,
499+ page_size : pageSize ,
500+ sort_order : sortOrder ,
501+ sort_column : helper . getSortColumnDBName ( sortColumn . toLowerCase ( ) ) ,
502+ handle : handle . toLowerCase ( )
503+ } ;
504+ async . parallel ( {
505+ data : exeQuery ( 'get_user_algo_challenges' ) ,
506+ count : exeQuery ( 'get_user_algo_challenges_count' )
507+ } , cb ) ;
508+ } ,
509+ function ( queryResult , cb ) {
510+ var total = queryResult . count [ 0 ] . total_count ;
511+ response = {
512+ pageIndex : pageIndex ,
513+ pageSize : pageIndex === - 1 ? total : pageSize ,
514+ total : total ,
515+ data : queryResult . data . map ( function ( row ) {
516+ return {
517+ id : row . id ,
518+ type : row . type ,
519+ prize : row . paid > 0 ,
520+ codingDuration : row . coding_duration ,
521+ placement : row . placement ,
522+ numContestants : row . num_contestants ,
523+ numSubmitters : row . num_submitters ,
524+ platforms : [ ] ,
525+ technologies : row . technologies . split ( ',' ) . map ( function ( s ) { return s . trim ( ) ; } )
526+ } ;
527+ } )
528+ } ;
529+ cb ( ) ;
530+ }
531+ ] , function ( err ) {
532+ if ( err ) {
533+ helper . handleError ( api , connection , err ) ;
534+ } else {
535+ connection . response = response ;
536+ }
537+ next ( connection , true ) ;
538+ } ) ;
539+ }
540+
541+ /**
542+ * The API for get user algorithm challenges.
543+ * @since 1.3
544+ */
545+ exports . getUserAlgorithmChallenges = {
546+ name : 'getUserAlgorithmChallenges' ,
547+ description : 'Get user algorithm challenges related information' ,
548+ inputs : {
549+ required : [ 'handle' ] ,
550+ optional : [ "sortOrder" , "pageIndex" , "pageSize" , "sortColumn" ]
551+ } ,
552+ blockedConnectionTypes : [ ] ,
553+ outputExample : { } ,
554+ version : 'v2' ,
555+ transaction : 'read' ,
556+ databases : [ 'topcoder_dw' , 'common_oltp' ] ,
557+ run : function ( api , connection , next ) {
558+ if ( connection . dbConnectionMap ) {
559+ api . log ( 'getUserAlgorithmChallenges#run' , 'debug' ) ;
560+ getUserAlgorithmChallenges ( api , connection , next ) ;
561+ } else {
562+ api . helper . handleNoConnection ( api , connection , next ) ;
563+ }
564+ }
565+ } ;
0 commit comments