diff --git a/lib/cartodb/models/mapconfig/adapter/mapconfig-overviews-adapter.js b/lib/cartodb/models/mapconfig/adapter/mapconfig-overviews-adapter.js index a104c592..e67a2513 100644 --- a/lib/cartodb/models/mapconfig/adapter/mapconfig-overviews-adapter.js +++ b/lib/cartodb/models/mapconfig/adapter/mapconfig-overviews-adapter.js @@ -1,4 +1,3 @@ -var step = require('step'); var queue = require('queue-async'); var _ = require('underscore'); @@ -9,93 +8,119 @@ function MapConfigOverviewsAdapter(overviewsMetadataBackend, filterStatsBackend) module.exports = MapConfigOverviewsAdapter; -MapConfigOverviewsAdapter.prototype.getMapConfig = function(user, requestMapConfig, params, context, callback) { - var self = this; - - var layers = requestMapConfig.layers; - var analysesResults = context.analysesResults; - - if (!layers || layers.length === 0) { - return callback(null, requestMapConfig); - } - - var augmentLayersQueue = queue(layers.length); - - function augmentLayer(layer, done) { - if ( layer.type !== 'mapnik' && layer.type !== 'cartodb' ) { - return done(null, layer); - } - self.overviewsMetadataBackend.getOverviewsMetadata(user, layer.options.sql, function(err, metadata){ - if (err) { - done(err, layer); - } else { - var query_rewrite_data = { overviews: metadata }; - step( - function collectFiltersData() { - var filters, unfiltered_query; - if ( layer.options.source && analysesResults && !layer.options.sql_wrap) { - var sourceId = layer.options.source.id; - var node = _.find(analysesResults, function(a){ return a.rootNode.params.id === sourceId; }); - if ( node ) { - node = node.rootNode; - filters = node.getFilters(); - var filters_disabler = Object.keys(filters).reduce( - function(disabler, filter_id){ disabler[filter_id] = false; return disabler; }, - {} - ); - unfiltered_query = node.getQuery(filters_disabler); - query_rewrite_data.filters = filters; - query_rewrite_data.unfiltered_query = unfiltered_query; - } - } - this(null, filters, unfiltered_query); - }, - function collectStatsData(err, filters, unfiltered_query) { - var next_step = this; - if ( filters ) { - self.filterStatsBackend.getFilterStats( - user, - unfiltered_query, filters, - function(err, stats) { - if ( !err ) { - query_rewrite_data.filter_stats = stats; - } - return next_step(err); - } - ); - } else { - return next_step(null); - } - }, - function addDataToLayer(err) { - if ( !err && !_.isEmpty(metadata) ) { - layer = _.extend({}, layer); - layer.options = _.extend({}, layer.options, { query_rewrite_data: query_rewrite_data }); - } - done(null, layer); - } - ); - } - }); - } - - function layersAugmentQueueFinish(err, layers) { - if (err) { - return callback(err); - } +MapConfigOverviewsAdapter.prototype.getMapConfig = function (user, requestMapConfig, params, context, callback) { + var layers = requestMapConfig.layers; + var analysesResults = context.analysesResults; if (!layers || layers.length === 0) { - return callback(new Error('Missing layers array from layergroup config')); + return callback(null, requestMapConfig); } - requestMapConfig.layers = layers; + var augmentLayersQueue = queue(layers.length); - return callback(null, requestMapConfig); - } + layers.forEach(layer => augmentLayersQueue.defer(this._augmentLayer.bind(this), user, layer, analysesResults)); - layers.forEach(function(layer) { - augmentLayersQueue.defer(augmentLayer, layer); - }); - augmentLayersQueue.awaitAll(layersAugmentQueueFinish); + augmentLayersQueue.awaitAll(function layersAugmentQueueFinish (err, layers) { + if (err) { + return callback(err); + } + if (!layers || layers.length === 0) { + return callback(new Error('Missing layers array from layergroup config')); + } + + requestMapConfig.layers = layers; + + return callback(null, requestMapConfig); + }); }; + +MapConfigOverviewsAdapter.prototype._augmentLayer = function (user, layer, analysesResults, callback) { + if (layer.type !== 'mapnik' && layer.type !== 'cartodb') { + return callback(null, layer); + } + + this.overviewsMetadataBackend.getOverviewsMetadata(user, layer.options.sql, (err, metadata) => { + if (err) { + return callback(err, layer); + } + + if (_.isEmpty(metadata)) { + return callback(null, layer); + } + + var filters = getFilters(analysesResults, layer); + + if (!filters) { + layer.options = Object.assign({}, layer.options, getQueryRewriteData(layer, analysesResults, { + overviews: metadata + })); + + return callback(null, layer); + } + + var unfilteredQuery = getUnfilteredQuery(analysesResults, layer); + + this.filterStatsBackend.getFilterStats(user, unfilteredQuery, filters, function (err, stats) { + if (err) { + return callback(null, layer); + } + + layer.options = Object.assign({}, layer.options, getQueryRewriteData(layer, analysesResults, { + overviews: metadata, + filter_stats: stats + })); + + return callback(null, layer); + }); + }); +}; + +function getRootNode (analysesResults, sourceId) { + var node = _.find(analysesResults, function (a) { + return a.rootNode.params.id === sourceId; + }); + + return node ? node.rootNode : undefined; +} + +function getFilters (analysesResults, layer) { + if (layer.options.source && analysesResults && !layer.options.sql_wrap) { + var sourceId = layer.options.source.id; + var node = getRootNode(analysesResults, sourceId); + + if (node) { + return node.getFilters(); + } + } +} + +function getUnfilteredQuery (analysesResults, layer) { + if (layer.options.source && analysesResults && !layer.options.sql_wrap) { + var sourceId = layer.options.source.id; + var node = getRootNode(analysesResults, sourceId); + + if (node) { + var filters = node.getFilters(); + var filters_disabler = Object.keys(filters).reduce(function (disabler, filter_id) { + disabler[filter_id] = false; + return disabler; + }, {}); + + return node.getQuery(filters_disabler); + } + } +} + +function getQueryRewriteData (layer, analysesResults, extend = {}) { + var queryRewriteData = {}; + + if (layer.options.source && analysesResults && !layer.options.sql_wrap) { + queryRewriteData.filters = getFilters(analysesResults, layer); + queryRewriteData.unfiltered_query = getUnfilteredQuery(analysesResults, layer); + } + + queryRewriteData = Object.assign({}, queryRewriteData, extend); + + return { query_rewrite_data: queryRewriteData }; +}