|
| 1 | +/* |
| 2 | + * Copyright (C) 2014 TopCoder Inc., All Rights Reserved. |
| 3 | + * |
| 4 | + * @version 1.0 |
| 5 | + * @author isv |
| 6 | + */ |
| 7 | +/*jslint node: true, nomen: true */ |
| 8 | + |
| 9 | +"use strict"; |
| 10 | + |
| 11 | +var async = require('async'); |
| 12 | +var _ = require('underscore'); |
| 13 | +var moment = require('moment'); |
| 14 | +var IllegalArgumentError = require('../errors/IllegalArgumentError'); |
| 15 | + |
| 16 | +/** |
| 17 | + * A value of 'pageIndex' request parameter to indicate that no paging of returned data is required. |
| 18 | + */ |
| 19 | +var NO_PAGING = -1; |
| 20 | + |
| 21 | +/** |
| 22 | + * A value of 'sortingOrder' request parameter to indicate that sorting in ascending order is requested. |
| 23 | + */ |
| 24 | +var SORTING_ORDER_ASCENDING = 'asc'; |
| 25 | + |
| 26 | +/** |
| 27 | + * A value of 'sortingOrder' request parameter to indicate that sorting in descending order is requested. |
| 28 | + */ |
| 29 | +var SORTING_ORDER_DESCENDING = 'desc'; |
| 30 | + |
| 31 | +/** |
| 32 | + * A list of names for columns in Past Data Science data. |
| 33 | + */ |
| 34 | +var PAST_CHALLENGES_DATA_COLUMN_NAMES = ['challengetype', 'challengename', 'challengeid', 'numsubmissions', |
| 35 | + 'numregistrants', 'registrationstartdate', 'submissionenddate', 'challengecommunity', 'postingdate']; |
| 36 | + |
| 37 | +/** |
| 38 | + * A format for the dates for Past Data Science Challenges filter. |
| 39 | + */ |
| 40 | +var PAST_CHALLENGES_FILTER_DATE_FORMAT = 'YYYY-MM-DD'; |
| 41 | + |
| 42 | +/** |
| 43 | + * A format for the dates for Past Data Science Challenges output. |
| 44 | + */ |
| 45 | +var PAST_CHALLENGES_OUTPUT_DATE_FORMAT = 'YYYY-MM-DD HH:mm z'; |
| 46 | + |
| 47 | +/** |
| 48 | + * Maximum value for integer number. |
| 49 | + */ |
| 50 | +var MAX_INT = 2147483647; |
| 51 | + |
| 52 | +/** |
| 53 | + * A name for the column to sort the data for past Data Science challenges by default. |
| 54 | + */ |
| 55 | +var PAST_CHALLENGES_DEFAULT_SORT_COLUMN = "submissionEndDate"; |
| 56 | + |
| 57 | +/** |
| 58 | + * An order to sort the data for past Data Science challenges by default. |
| 59 | + */ |
| 60 | +var PAST_CHALLENGES_DEFAULT_SORT_ORDER = "desc"; |
| 61 | + |
| 62 | +/** |
| 63 | + * Gets the details for the past Data Science challenges and provides it to specified callback. |
| 64 | + * |
| 65 | + * @param {Number} pageIndex - an index of the page of the data to be returned or -1 if no paging is required. |
| 66 | + * @param {Number} pageSize - a size of page of the data to be returned or 0 if pageIndex is -1. |
| 67 | + * @param {String} sortingColumnName - a name of the column to sort the data against. Must not be null. |
| 68 | + * @param {String} sortingOrder - a sorting order (either 'asc' or 'desc'). Must not be null. |
| 69 | + * @param {Date} submissionEndFrom - a lower boundary for the submission end date filter. Must not be null. |
| 70 | + * @param {Date} submissionEndTo - - an upper boundary for the submission end date filter. Must not be null. |
| 71 | + * @param {Object} api - an action hero api object. |
| 72 | + * @param {Object} connection - a connection object for the current request. |
| 73 | + * @param callback - a callback to be notified on retrieved data matching the specified criteria. |
| 74 | + */ |
| 75 | +function pastDataScienceChallenges(pageIndex, pageSize, sortingColumnName, sortingOrder, submissionEndFrom, |
| 76 | + submissionEndTo, api, connection, callback) { |
| 77 | + if (pageIndex === NO_PAGING) { |
| 78 | + pageIndex = 1; |
| 79 | + pageSize = MAX_INT; |
| 80 | + } |
| 81 | + |
| 82 | + var sqlParams = {}; |
| 83 | + sqlParams.firstRowIndex = (pageIndex - 1) * pageSize; |
| 84 | + sqlParams.pageSize = pageSize; |
| 85 | + sqlParams.sortColumn = api.helper.getSortColumnDBName(sortingColumnName); |
| 86 | + sqlParams.sortOrder = sortingOrder; |
| 87 | + sqlParams.submitByFrom = submissionEndFrom; |
| 88 | + sqlParams.submitByTo = submissionEndTo; |
| 89 | + |
| 90 | + async.parallel({ |
| 91 | + total: function (cb) { |
| 92 | + api.dataAccess.executeQuery('past_data_science_challenges_count', sqlParams, connection.dbConnectionMap, cb); |
| 93 | + }, |
| 94 | + data: function (cb) { |
| 95 | + api.dataAccess.executeQuery('past_data_science_challenges', sqlParams, connection.dbConnectionMap, cb); |
| 96 | + } |
| 97 | + }, function (err, results) { |
| 98 | + if (err) { |
| 99 | + callback(err); |
| 100 | + } else { |
| 101 | + callback(null, results.total[0].total_count, results.data); |
| 102 | + } |
| 103 | + }); |
| 104 | +} |
| 105 | + |
| 106 | + |
| 107 | +/** |
| 108 | + * View Past Data Science Challenges API. |
| 109 | + */ |
| 110 | +exports.pastDataScienceChallenges = { |
| 111 | + name: 'pastDataScienceChallenges', |
| 112 | + description: 'Get the list of past Data Science challenges', |
| 113 | + inputs: { |
| 114 | + required: [], |
| 115 | + optional: ['pageIndex', 'pageSize', 'sortColumn', 'sortOrder', 'submissionEndFrom', 'submissionEndTo'] |
| 116 | + }, |
| 117 | + blockedConnectionTypes: [], |
| 118 | + outputExample: {}, |
| 119 | + version: 'v2', |
| 120 | + cacheEnabled: false, |
| 121 | + transaction: 'read', |
| 122 | + databases: ['tcs_dw'], |
| 123 | + run: function (api, connection, next) { |
| 124 | + if (connection.dbConnectionMap) { |
| 125 | + api.log('Execute pastDataScienceChallenges#run', 'debug'); |
| 126 | + var pageIndex, |
| 127 | + pageSize, |
| 128 | + sortingColumnName, |
| 129 | + sortingOrder, |
| 130 | + submissionEndFrom, |
| 131 | + submissionEndTo, |
| 132 | + err, |
| 133 | + helper = api.helper; |
| 134 | + |
| 135 | + async.waterfall([ |
| 136 | + function (cb) { // Parse and validate request parameters |
| 137 | + pageIndex = Number(connection.params.pageIndex || 1); |
| 138 | + pageSize = Number(connection.params.pageSize || 50); |
| 139 | + sortingOrder = connection.params.sortOrder || PAST_CHALLENGES_DEFAULT_SORT_ORDER; |
| 140 | + sortingColumnName = connection.params.sortColumn || PAST_CHALLENGES_DEFAULT_SORT_COLUMN; |
| 141 | + |
| 142 | + err = helper.checkContains([SORTING_ORDER_ASCENDING, SORTING_ORDER_DESCENDING], sortingOrder.toLowerCase(), "sortOrder") |
| 143 | + || helper.checkContains(PAST_CHALLENGES_DATA_COLUMN_NAMES, sortingColumnName.toLowerCase(), "sortColumn") |
| 144 | + || helper.checkPageIndex(pageIndex, "pageIndex") |
| 145 | + || helper.checkPositiveInteger(pageSize, "pageSize") |
| 146 | + || helper.checkMaxInt(pageSize, 'pageSize'); |
| 147 | + |
| 148 | + if (err) { |
| 149 | + cb(err); |
| 150 | + return; |
| 151 | + } |
| 152 | + |
| 153 | + if (_.isDefined(connection.params.submissionEndFrom)) { |
| 154 | + err = helper.checkDateFormat(connection.params.submissionEndFrom, |
| 155 | + PAST_CHALLENGES_FILTER_DATE_FORMAT, 'submissionEndFrom'); |
| 156 | + if (err) { |
| 157 | + cb(err); |
| 158 | + return; |
| 159 | + } |
| 160 | + submissionEndFrom = connection.params.submissionEndFrom; |
| 161 | + } else { |
| 162 | + submissionEndFrom = '1900-01-01'; |
| 163 | + } |
| 164 | + if (_.isDefined(connection.params.submissionEndTo)) { |
| 165 | + err = helper.checkDateFormat(connection.params.submissionEndTo, |
| 166 | + PAST_CHALLENGES_FILTER_DATE_FORMAT, 'submissionEndTo'); |
| 167 | + if (err) { |
| 168 | + cb(err); |
| 169 | + return; |
| 170 | + } |
| 171 | + submissionEndTo = connection.params.submissionEndTo; |
| 172 | + } else { |
| 173 | + submissionEndTo = '2999-12-31'; |
| 174 | + } |
| 175 | + |
| 176 | + err = helper.checkDates(submissionEndFrom, submissionEndTo, |
| 177 | + 'submissionEndFrom must be before submissionEndTo'); |
| 178 | + if (err) { |
| 179 | + cb(err); |
| 180 | + return; |
| 181 | + } |
| 182 | + |
| 183 | + cb(); |
| 184 | + }, function (cb) { // Get the data based on requested parameters once provided parameters are valid |
| 185 | + pastDataScienceChallenges(pageIndex, pageSize, sortingColumnName, sortingOrder, submissionEndFrom, |
| 186 | + submissionEndTo, api, connection, cb); |
| 187 | + } |
| 188 | + ], function (err, total, data) { |
| 189 | + if (err) { |
| 190 | + helper.handleError(api, connection, err); |
| 191 | + } else { |
| 192 | + // Build the response from the results |
| 193 | + var response = {}; |
| 194 | + response.total = total; |
| 195 | + response.data = []; |
| 196 | + |
| 197 | + // Copy request parameters for filter into response |
| 198 | + if (_.isDefined(connection.params.pageIndex)) { |
| 199 | + response.pageIndex = connection.params.pageIndex; |
| 200 | + } |
| 201 | + if (_.isDefined(connection.params.pageSize)) { |
| 202 | + response.pageSize = connection.params.pageSize; |
| 203 | + } |
| 204 | + if (_.isDefined(connection.params.sortColumn)) { |
| 205 | + response.sortColumn = connection.params.sortColumn; |
| 206 | + } |
| 207 | + if (_.isDefined(connection.params.sortOrder)) { |
| 208 | + response.sortOrder = connection.params.sortOrder; |
| 209 | + } |
| 210 | + if (_.isDefined(connection.params.submissionEndFrom)) { |
| 211 | + response.submissionEndFrom = connection.params.submissionEndFrom; |
| 212 | + } |
| 213 | + if (_.isDefined(connection.params.submissionEndTo)) { |
| 214 | + response.submissionEndTo = connection.params.submissionEndTo; |
| 215 | + } |
| 216 | + // Convert the rows returned from DB into format suitable for response |
| 217 | + _.each(data, function (row) { |
| 218 | + var challenge = { |
| 219 | + challengeType: row.challenge_type, |
| 220 | + challengeName: row.challenge_name, |
| 221 | + challengeId: row.challenge_id, |
| 222 | + numSubmissions: row.num_submissions, |
| 223 | + numRegistrants: row.num_registrants, |
| 224 | + registrationStartDate: helper.formatDateWithTimezone(row.registration_start_date, PAST_CHALLENGES_OUTPUT_DATE_FORMAT), |
| 225 | + submissionEndDate: helper.formatDateWithTimezone(row.submission_end_date, PAST_CHALLENGES_OUTPUT_DATE_FORMAT), |
| 226 | + challengeCommunity: row.challenge_community, |
| 227 | + postingDate: helper.formatDateWithTimezone(row.posting_date, PAST_CHALLENGES_OUTPUT_DATE_FORMAT) |
| 228 | + }; |
| 229 | + response.data.push(challenge); |
| 230 | + }); |
| 231 | + |
| 232 | + |
| 233 | + connection.response = response; |
| 234 | + } |
| 235 | + next(connection, true); |
| 236 | + }); |
| 237 | + } else { |
| 238 | + api.helper.handleNoConnection(api, connection, next); |
| 239 | + } |
| 240 | + } |
| 241 | +}; |
0 commit comments