diff --git a/lib/cartodb/backends/cluster.js b/lib/cartodb/backends/cluster.js index f858b27a..113dde65 100644 --- a/lib/cartodb/backends/cluster.js +++ b/lib/cartodb/backends/cluster.js @@ -6,8 +6,6 @@ const debug = require('debug')('backend:cluster'); const AggregationMapConfig = require('../models/aggregation/aggregation-mapconfig'); module.exports = class ClusterBackend { - // TODO: reduce complexity - // jshint maxcomplexity: 10 getClusterFeatures (mapConfigProvider, params, callback) { mapConfigProvider.getMapConfig((err, _mapConfig) => { if (err) { @@ -43,54 +41,19 @@ module.exports = class ClusterBackend { let { aggregation } = params; - if (aggregation !== undefined) { - try { - aggregation = JSON.parse(aggregation); - } catch (err) { - const error = new Error(`Invalid aggregation input, should be a a valid JSON`); - error.http_status = 400; - error.type = 'layer'; - error.subtype = 'aggregation'; - error.layer = { - index: layerIndex, - type: layer.type - }; + try { + aggregation = parseAggregation(aggregation); + validateAggregation(aggregation); + } catch (error) { + error.http_status = 400; + error.type = 'layer'; + error.subtype = 'aggregation'; + error.layer = { + index: layerIndex, + type: layer.type + }; - return callback(error); - } - - const { columns, expressions } = aggregation; - - if (!hasColumns(columns)) { - const error = new Error( - `Invalid aggregation input, columns should be and array of column names` - ); - error.http_status = 400; - error.type = 'layer'; - error.subtype = 'aggregation'; - error.layer = { - index: layerIndex, - type: layer.type - }; - - return callback(error); - } - - if (expressions !== undefined) { - try { - validateExpressions(expressions); - } catch (error) { - error.http_status = 400; - error.type = 'layer'; - error.subtype = 'aggregation'; - error.layer = { - index: layerIndex, - type: layer.type - }; - - return callback(error); - } - } + return callback(error); } const query = layer.options.sql_raw; @@ -229,22 +192,49 @@ function hasAggregationLayer (mapConfig, layerIndex) { return mapConfig.isAggregationLayer(layerIndex); } +function parseAggregation (aggregation) { + if (aggregation !== undefined) { + try { + aggregation = JSON.parse(aggregation); + } catch (err) { + throw new Error(`Invalid aggregation input, should be a a valid JSON`); + } + + } + + return aggregation; +} + +function validateAggregation (aggregation) { + if (aggregation !== undefined) { + const { columns, expressions } = aggregation; + + if (!hasColumns(columns)) { + throw new Error(`Invalid aggregation input, columns should be and array of column names`); + } + + validateExpressions(expressions); + } +} + function hasColumns (columns) { return Array.isArray(columns) && columns.length; } function validateExpressions (expressions) { - if (!isValidExpression(expressions)) { - throw new Error(`Invalid aggregation input, expressions should be and object with valid functions`); - } - - for (const { aggregate_function, aggregated_column } of Object.values(expressions)) { - if (typeof aggregated_column !== 'string') { - throw new Error(`Invalid aggregation input, aggregated column should be an string`); + if (expressions !== undefined) { + if (!isValidExpression(expressions)) { + throw new Error(`Invalid aggregation input, expressions should be and object with valid functions`); } - if (typeof aggregate_function !== 'string') { - throw new Error(`Invalid aggregation input, aggregate function should be an string`); + for (const { aggregate_function, aggregated_column } of Object.values(expressions)) { + if (typeof aggregated_column !== 'string') { + throw new Error(`Invalid aggregation input, aggregated column should be an string`); + } + + if (typeof aggregate_function !== 'string') { + throw new Error(`Invalid aggregation input, aggregate function should be an string`); + } } } }