Windshaft-cartodb/lib/models/mapconfig/adapter/mapconfig-overviews-adapter.js
2019-10-07 09:40:50 +02:00

140 lines
4.7 KiB
JavaScript

'use strict';
var queue = require('queue-async');
var _ = require('underscore');
const AggregationMapConfig = require('../../aggregation/aggregation-mapconfig');
function MapConfigOverviewsAdapter(overviewsMetadataBackend, filterStatsBackend) {
this.overviewsMetadataBackend = overviewsMetadataBackend;
this.filterStatsBackend = filterStatsBackend;
}
module.exports = MapConfigOverviewsAdapter;
MapConfigOverviewsAdapter.prototype.getMapConfig = function (user, requestMapConfig, params, context, callback) {
var layers = requestMapConfig.layers;
var analysesResults = context.analysesResults;
const aggMapConfig = new AggregationMapConfig(null, requestMapConfig);
if (aggMapConfig.isVectorOnlyMapConfig() || aggMapConfig.isAggregationMapConfig() ||
!layers || layers.length === 0) {
return callback(null, requestMapConfig);
}
var augmentLayersQueue = queue(layers.length);
layers.forEach(layer => augmentLayersQueue.defer(this._augmentLayer.bind(this), user, layer, analysesResults));
augmentLayersQueue.awaitAll(function layersAugmentQueueFinish (err, results) {
if (err) {
return callback(err);
}
const layers = results.map(result => result.layer);
const overviewsAddedToMapconfig = results.some(result => result.overviewsAddedToMapconfig);
if (!layers || layers.length === 0) {
return callback(new Error('Missing layers array from layergroup config'));
}
requestMapConfig.layers = layers;
const stats = { overviewsAddedToMapconfig };
return callback(null, requestMapConfig, stats);
});
};
MapConfigOverviewsAdapter.prototype._augmentLayer = function (user, layer, analysesResults, callback) {
let overviewsAddedToMapconfig = false;
if (layer.type !== 'mapnik' && layer.type !== 'cartodb') {
return callback(null, { layer, overviewsAddedToMapconfig });
}
this.overviewsMetadataBackend.getOverviewsMetadata(user, layer.options.sql, (err, metadata) => {
if (err) {
return callback(err, { layer, overviewsAddedToMapconfig });
}
if (_.isEmpty(metadata)) {
return callback(null, { layer, overviewsAddedToMapconfig });
}
var filters = getFilters(analysesResults, layer);
overviewsAddedToMapconfig = true;
if (!filters) {
layer.options = Object.assign({}, layer.options, getQueryRewriteData(layer, analysesResults, {
overviews: metadata
}));
return callback(null, { layer, overviewsAddedToMapconfig });
}
var unfilteredQuery = getUnfilteredQuery(analysesResults, layer);
this.filterStatsBackend.getFilterStats(user, unfilteredQuery, filters, function (err, stats) {
if (err) {
return callback(null, { layer, overviewsAddedToMapconfig });
}
layer.options = Object.assign({}, layer.options, getQueryRewriteData(layer, analysesResults, {
overviews: metadata,
filter_stats: stats
}));
return callback(null, { layer, overviewsAddedToMapconfig });
});
});
};
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 };
}