diff --git a/lib/cartodb/controllers/map.js b/lib/cartodb/controllers/map.js index 93a917b8..1510dfc2 100644 --- a/lib/cartodb/controllers/map.js +++ b/lib/cartodb/controllers/map.js @@ -111,26 +111,6 @@ MapController.prototype.checkJsonContentType = function () { }; }; -MapController.prototype.checkCreateLayergroup = function () { - return function checkCreateLayergroupMiddleware (req, res, next) { - if (req.method === 'GET') { - const { config } = res.locals; - - if (!config) { - return next(new Error('layergroup GET needs a "config" parameter')); - } - - try { - req.body = JSON.parse(config); - } catch (err) { - return next(err); - } - } - - return next(); - }; -}; - MapController.prototype.checkInstantiteLayergroup = function () { return function checkInstantiteLayergroupMiddleware(req, res, next) { if (req.method === 'GET') { @@ -153,6 +133,58 @@ MapController.prototype.checkInstantiteLayergroup = function () { }; }; +MapController.prototype.checkCreateLayergroup = function () { + return function checkCreateLayergroupMiddleware (req, res, next) { + if (req.method === 'GET') { + const { config } = res.locals; + + if (!config) { + return next(new Error('layergroup GET needs a "config" parameter')); + } + + try { + req.body = JSON.parse(config); + } catch (err) { + return next(err); + } + } + + return next(); + }; +}; + +MapController.prototype.getTemplate = function () { + return function getTemplateMiddleware (req, res, next) { + const templateParams = req.body; + const { user } = res.locals; + + const mapconfigProvider = new NamedMapMapConfigProvider( + this.templateMaps, + this.pgConnection, + this.metadataBackend, + this.userLimitsApi, + this.mapConfigAdapter, + user, + req.params.template_id, + templateParams, + res.locals.auth_token, + res.locals + ); + + mapconfigProvider.getMapConfig((err, mapconfig, rendererParams) => { + if (err) { + return next(err); + } + + res.locals.mapconfig = mapconfig; + res.locals.rendererParams = rendererParams; + res.locals.mapconfigProvider = mapconfigProvider; + + next(); + }); + }.bind(this); +}; + MapController.prototype.prepareAdapterMapConfig = function () { return function prepareAdapterMapConfigMiddleware(req, res, next) { const requestMapConfig = req.body; @@ -212,38 +244,6 @@ MapController.prototype.createLayergroup = function () { }.bind(this); }; -MapController.prototype.getTemplate = function () { - return function getTemplateMiddleware (req, res, next) { - const templateParams = req.body; - const { user } = res.locals; - - const mapconfigProvider = new NamedMapMapConfigProvider( - this.templateMaps, - this.pgConnection, - this.metadataBackend, - this.userLimitsApi, - this.mapConfigAdapter, - user, - req.params.template_id, - templateParams, - res.locals.auth_token, - res.locals - ); - - mapconfigProvider.getMapConfig((err, mapconfig, rendererParams) => { - if (err) { - return next(err); - } - - res.locals.mapconfig = mapconfig; - res.locals.rendererParams = rendererParams; - res.locals.mapconfigProvider = mapconfigProvider; - - next(); - }); - }.bind(this); -}; - MapController.prototype.instantiateLayergroup = function () { return function instantiateLayergroupMiddleware (req, res, next) { const { user, mapconfig, rendererParams } = res.locals; @@ -269,20 +269,6 @@ MapController.prototype.instantiateLayergroup = function () { }.bind(this); }; -MapController.prototype.sendResponse = function () { - return function sendResponseMiddleware (req, res) { - const { layergroup } = res.locals; - - res.status(200); - - if (req.query && req.query.callback) { - res.jsonp(layergroup); - } else { - res.json(layergroup); - } - }; -}; - MapController.prototype.incrementMapViewCount = function () { return function incrementMapViewCountMiddleware(req, res, next) { const { mapconfig, user } = res.locals; @@ -377,6 +363,19 @@ MapController.prototype.setLastUpdatedTimeToLayergroup = function () { }; }; +function getLastUpdatedTime(analysesResults, lastUpdateTime) { + if (!Array.isArray(analysesResults)) { + return lastUpdateTime; + } + return analysesResults.reduce(function(lastUpdateTime, analysis) { + return analysis.getNodes().reduce(function(lastNodeUpdatedAtTime, node) { + var nodeUpdatedAtDate = node.getUpdatedAt(); + var nodeUpdatedTimeAt = (nodeUpdatedAtDate && nodeUpdatedAtDate.getTime()) || 0; + return nodeUpdatedTimeAt > lastNodeUpdatedAtTime ? nodeUpdatedTimeAt : lastNodeUpdatedAtTime; + }, lastUpdateTime); + }, lastUpdateTime); +} + MapController.prototype.setCacheControl = function () { return function setCacheControlMiddleware (req, res, next) { if (req.method === 'GET') { @@ -439,96 +438,6 @@ MapController.prototype.setDataviewsAndWidgetsUrlsToLayergroupMetadata = functio }.bind(this); }; -MapController.prototype.setAnalysesMetadataToLayergroup = function (includeQuery) { - return function setAnalysesMetadataToLayergroupMiddleware (req, res, next) { - const { layergroup, user, analysesResults = [] } = res.locals; - - this.addAnalysesMetadata(user, layergroup, analysesResults, includeQuery); - - next(); - }.bind(this); -}; - -MapController.prototype.setTurboCartoMetadataToLayergroup = function () { - return function (req, res, next) { - const { layergroup, mapconfig, context } = res.locals; - - addContextMetadata(layergroup, mapconfig.obj(), context); - - next(); - }; -}; - -function addContextMetadata(layergroup, mapConfig, context) { - if (layergroup.metadata && Array.isArray(layergroup.metadata.layers) && Array.isArray(mapConfig.layers)) { - layergroup.metadata.layers = layergroup.metadata.layers.map(function(layer, layerIndex) { - if (context.turboCarto && Array.isArray(context.turboCarto.layers)) { - layer.meta.cartocss_meta = context.turboCarto.layers[layerIndex]; - } - return layer; - }); - } -} - -MapController.prototype.setSurrogateKeyHeader = function () { - return function setSurrogateKeyHeaderMiddleware(req, res, next) { - const { affectedTables, user, templateName } = res.locals; - - if (req.method === 'GET' && affectedTables.tables && affectedTables.tables.length > 0) { - this.surrogateKeysCache.tag(res, affectedTables); - } - - if (templateName) { - this.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(user, templateName)); - } - - next(); - }.bind(this); -}; - -function getLastUpdatedTime(analysesResults, lastUpdateTime) { - if (!Array.isArray(analysesResults)) { - return lastUpdateTime; - } - return analysesResults.reduce(function(lastUpdateTime, analysis) { - return analysis.getNodes().reduce(function(lastNodeUpdatedAtTime, node) { - var nodeUpdatedAtDate = node.getUpdatedAt(); - var nodeUpdatedTimeAt = (nodeUpdatedAtDate && nodeUpdatedAtDate.getTime()) || 0; - return nodeUpdatedTimeAt > lastNodeUpdatedAtTime ? nodeUpdatedTimeAt : lastNodeUpdatedAtTime; - }, lastUpdateTime); - }, lastUpdateTime); -} - -MapController.prototype.addAnalysesMetadata = function(username, layergroup, analysesResults, includeQuery) { - includeQuery = includeQuery || false; - analysesResults = analysesResults || []; - layergroup.metadata.analyses = []; - - analysesResults.forEach(function(analysis) { - var nodes = analysis.getNodes(); - layergroup.metadata.analyses.push({ - nodes: nodes.reduce(function(nodesIdMap, node) { - if (node.params.id) { - var nodeResource = layergroup.layergroupid + '/analysis/node/' + node.id(); - var nodeRepr = { - status: node.getStatus(), - url: this.resourceLocator.getUrls(username, nodeResource) - }; - if (includeQuery) { - nodeRepr.query = node.getQuery(); - } - if (node.getStatus() === 'failed') { - nodeRepr.error_message = node.getErrorMessage(); - } - nodesIdMap[node.params.id] = nodeRepr; - } - - return nodesIdMap; - }.bind(this), {}) - }); - }.bind(this)); -}; - // TODO this should take into account several URL patterns MapController.prototype.addDataviewsAndWidgetsUrls = function(username, layergroup, mapConfig) { this.addDataviewsUrls(username, layergroup, mapConfig); @@ -566,6 +475,97 @@ MapController.prototype.addWidgetsUrl = function(username, layergroup, mapConfig } }; +MapController.prototype.setAnalysesMetadataToLayergroup = function (includeQuery) { + return function setAnalysesMetadataToLayergroupMiddleware (req, res, next) { + const { layergroup, user, analysesResults = [] } = res.locals; + + this.addAnalysesMetadata(user, layergroup, analysesResults, includeQuery); + + next(); + }.bind(this); +}; + +MapController.prototype.addAnalysesMetadata = function(username, layergroup, analysesResults, includeQuery) { + includeQuery = includeQuery || false; + analysesResults = analysesResults || []; + layergroup.metadata.analyses = []; + + analysesResults.forEach(function(analysis) { + var nodes = analysis.getNodes(); + layergroup.metadata.analyses.push({ + nodes: nodes.reduce(function(nodesIdMap, node) { + if (node.params.id) { + var nodeResource = layergroup.layergroupid + '/analysis/node/' + node.id(); + var nodeRepr = { + status: node.getStatus(), + url: this.resourceLocator.getUrls(username, nodeResource) + }; + if (includeQuery) { + nodeRepr.query = node.getQuery(); + } + if (node.getStatus() === 'failed') { + nodeRepr.error_message = node.getErrorMessage(); + } + nodesIdMap[node.params.id] = nodeRepr; + } + + return nodesIdMap; + }.bind(this), {}) + }); + }.bind(this)); +}; + +MapController.prototype.setTurboCartoMetadataToLayergroup = function () { + return function setTurboCartoMetadataToLayergroupMiddleware (req, res, next) { + const { layergroup, mapconfig, context } = res.locals; + + addContextMetadata(layergroup, mapconfig.obj(), context); + + next(); + }; +}; + +function addContextMetadata(layergroup, mapConfig, context) { + if (layergroup.metadata && Array.isArray(layergroup.metadata.layers) && Array.isArray(mapConfig.layers)) { + layergroup.metadata.layers = layergroup.metadata.layers.map(function(layer, layerIndex) { + if (context.turboCarto && Array.isArray(context.turboCarto.layers)) { + layer.meta.cartocss_meta = context.turboCarto.layers[layerIndex]; + } + return layer; + }); + } +} + +MapController.prototype.setSurrogateKeyHeader = function () { + return function setSurrogateKeyHeaderMiddleware(req, res, next) { + const { affectedTables, user, templateName } = res.locals; + + if (req.method === 'GET' && affectedTables.tables && affectedTables.tables.length > 0) { + this.surrogateKeysCache.tag(res, affectedTables); + } + + if (templateName) { + this.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(user, templateName)); + } + + next(); + }.bind(this); +}; + +MapController.prototype.sendResponse = function () { + return function sendResponseMiddleware (req, res) { + const { layergroup } = res.locals; + + res.status(200); + + if (req.query && req.query.callback) { + res.jsonp(layergroup); + } else { + res.json(layergroup); + } + }; +}; + MapController.prototype.augmentError = function (options) { const { addContext = false, label = 'MAPS CONTROLLER' } = options;