diff --git a/lib/cartodb/backends/dataview.js b/lib/cartodb/backends/dataview.js index 4eebb2a2..542bbb4e 100644 --- a/lib/cartodb/backends/dataview.js +++ b/lib/cartodb/backends/dataview.js @@ -1,7 +1,5 @@ -var assert = require('assert'); var _ = require('underscore'); var PSQL = require('cartodb-psql'); -var step = require('step'); var BBoxFilter = require('../models/filter/bbox'); var DataviewFactory = require('../models/dataview/factory'); var DataviewFactoryWithOverviews = require('../models/dataview/overviews/factory'); @@ -21,53 +19,76 @@ function DataviewBackend(analysisBackend) { module.exports = DataviewBackend; DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, params, callback) { + const dataviewName = params.dataviewName; - var dataviewName = params.dataviewName; - step( - function getMapConfig() { - mapConfigProvider.getMapConfig(this); - }, - function runDataviewQuery(err, mapConfig) { - assert.ifError(err); + mapConfigProvider.getMapConfig(function (err, mapConfig) { + if (err) { + return callback(err); + } - var dataviewDefinition = getDataviewDefinition(mapConfig.obj(), dataviewName); - if (!dataviewDefinition) { - throw new Error("Dataview '" + dataviewName + "' does not exists"); - } + var dataviewDefinition = getDataviewDefinition(mapConfig.obj(), dataviewName); + if (!dataviewDefinition) { + const error = new Error(`Dataview '${dataviewName}' does not exists`); + error.type = 'dataview'; + error.http_status = 400; + return callback(error); + } + if (!validFilterParams(params)) { + const error = new Error('Both own_filter and no_filters cannot be sent in the same request'); + error.type = 'dataview'; + error.http_status = 400; + return callback(error); + } + + var pg; + var overrideParams; + var dataview; + + try { + pg = new PSQL(dbParamsFromReqParams(params)); + var query = getQueryWithFilters(dataviewDefinition, params); + var queryRewriteData = getQueryRewriteData(mapConfig, dataviewDefinition, params); + var dataviewFactory = DataviewFactoryWithOverviews.getFactory(overviewsQueryRewriter, queryRewriteData, { + bbox: params.bbox + }); + dataview = dataviewFactory.getDataview(query, dataviewDefinition); var ownFilter = +params.own_filter; - var noFilters = +params.no_filters; - if (Number.isFinite(ownFilter) && Number.isFinite(noFilters)) { - err = new Error(); - err.message = 'Both own_filter and no_filters cannot be sent in the same request'; - err.type = 'dataview'; - err.http_status = 400; + overrideParams = getOverrideParams(params, !!ownFilter); + } catch (error) { + return callback(error); + } + + dataview.getResult(pg, overrideParams, function (err, dataviewResult) { + if (err) { return callback(err); } - var pg = new PSQL(dbParamsFromReqParams(params)); - - var query = getDataviewQuery(dataviewDefinition, ownFilter, noFilters); - if (params.bbox) { - var bboxFilter = new BBoxFilter({column: 'the_geom_webmercator', srid: 3857}, {bbox: params.bbox}); - query = bboxFilter.sql(query); - } - - var queryRewriteData = getQueryRewriteData(mapConfig, dataviewDefinition, params); - - var dataviewFactory = DataviewFactoryWithOverviews.getFactory( - overviewsQueryRewriter, queryRewriteData, { bbox: params.bbox } - ); - - var dataview = dataviewFactory.getDataview(query, dataviewDefinition); - dataview.getResult(pg, getOverrideParams(params, !!ownFilter), this); - }, - function returnCallback(err, result) { - return callback(err, result); - } - ); + return callback(null, dataviewResult); + }); + }); }; +function validFilterParams (params) { + var ownFilter = +params.own_filter; + var noFilters = +params.no_filters; + + return !(Number.isFinite(ownFilter) && Number.isFinite(noFilters)); +} + +function getQueryWithFilters (dataviewDefinition, params) { + var ownFilter = +params.own_filter; + var noFilters = +params.no_filters; + var query = getDataviewQuery(dataviewDefinition, ownFilter, noFilters); + + if (params.bbox) { + var bboxFilter = new BBoxFilter({column: 'the_geom_webmercator', srid: 3857}, {bbox: params.bbox}); + query = bboxFilter.sql(query); + } + + return query; +} + function getDataviewQuery(dataviewDefinition, ownFilter, noFilters) { if (noFilters) { return dataviewDefinition.sql.no_filters; @@ -129,41 +150,56 @@ function getOverrideParams(params, ownFilter) { } DataviewBackend.prototype.search = function (mapConfigProvider, user, dataviewName, params, callback) { - step( - function getMapConfig() { - mapConfigProvider.getMapConfig(this); - }, - function runDataviewSearchQuery(err, mapConfig) { - assert.ifError(err); - - var dataviewDefinition = getDataviewDefinition(mapConfig.obj(), dataviewName); - if (!dataviewDefinition) { - throw new Error("Dataview '" + dataviewName + "' does not exists"); - } - - var pg = new PSQL(dbParamsFromReqParams(params)); - - var ownFilter = +params.own_filter; - ownFilter = !!ownFilter; - - var query = (ownFilter) ? dataviewDefinition.sql.own_filter_on : dataviewDefinition.sql.own_filter_off; - - if (params.bbox) { - var bboxFilter = new BBoxFilter({column: 'the_geom', srid: 4326}, {bbox: params.bbox}); - query = bboxFilter.sql(query); - } - - var userQuery = params.q; - - var dataview = DataviewFactory.getDataview(query, dataviewDefinition); - dataview.search(pg, userQuery, this); - }, - function returnCallback(err, result) { - return callback(err, result); + mapConfigProvider.getMapConfig(function (err, mapConfig) { + if (err) { + return callback(err); } - ); + + var dataviewDefinition = getDataviewDefinition(mapConfig.obj(), dataviewName); + if (!dataviewDefinition) { + const error = new Error(`Dataview '${dataviewName}' does not exists`); + error.type = 'dataview'; + error.http_status = 400; + return callback(error); + } + + var pg; + var query; + var dataview; + var userQuery = params.q; + + try { + pg = new PSQL(dbParamsFromReqParams(params)); + query = getQueryWithOwnFilters(dataviewDefinition, params); + dataview = DataviewFactory.getDataview(query, dataviewDefinition); + } catch (error) { + return callback(error); + } + + dataview.search(pg, userQuery, function (err, result) { + if (err) { + return callback(err); + } + + return callback(null, result); + }); + }); }; +function getQueryWithOwnFilters (dataviewDefinition, params) { + var ownFilter = +params.own_filter; + ownFilter = !!ownFilter; + + var query = (ownFilter) ? dataviewDefinition.sql.own_filter_on : dataviewDefinition.sql.own_filter_off; + + if (params.bbox) { + var bboxFilter = new BBoxFilter({ column: 'the_geom', srid: 4326 }, { bbox: params.bbox }); + query = bboxFilter.sql(query); + } + + return query; +} + function getDataviewDefinition(mapConfig, dataviewName) { var dataviews = mapConfig.dataviews || {}; return dataviews[dataviewName]; diff --git a/lib/cartodb/backends/filter-stats.js b/lib/cartodb/backends/filter-stats.js index ba427405..b37d8704 100644 --- a/lib/cartodb/backends/filter-stats.js +++ b/lib/cartodb/backends/filter-stats.js @@ -1,5 +1,4 @@ var _ = require('underscore'); -var step = require('step'); var AnalysisFilter = require('../models/filter/analysis'); function FilterStatsBackends(pgQueryRunner) { @@ -24,36 +23,29 @@ function getEstimatedRows(pgQueryRunner, username, query, callback) { } FilterStatsBackends.prototype.getFilterStats = function (username, unfiltered_query, filters, callback) { - var stats = {}; - var self = this; - step( - function getUnfilteredRows() { - getEstimatedRows(self.pgQueryRunner, username, unfiltered_query, this); - }, - function receiveUnfilteredRows(err, rows) { - if (err){ - callback(err); - return; - } - stats.unfiltered_rows = rows; - this(null, rows); - }, - function getFilteredRows() { - if ( filters && !_.isEmpty(filters)) { - var analysisFilter = new AnalysisFilter(filters); - var query = analysisFilter.sql(unfiltered_query); - getEstimatedRows(self.pgQueryRunner, username, query, this); - } else { - this(null, null); - } - }, - function receiveFilteredRows(err, rows) { - if (err){ - callback(err); - return; - } - stats.filtered_rows = rows; - callback(null, stats); - } - ); + var stats = {}; + + getEstimatedRows(this.pgQueryRunner, username, unfiltered_query, (err, rows) => { + if (err){ + return callback(err); + } + + stats.unfiltered_rows = rows; + + if (!filters || _.isEmpty(filters)) { + return callback(null, stats); + } + + var analysisFilter = new AnalysisFilter(filters); + var query = analysisFilter.sql(unfiltered_query); + + getEstimatedRows(this.pgQueryRunner, username, query, (err, rows) => { + if (err){ + return callback(err); + } + + stats.filtered_rows = rows; + return callback(null, stats); + }); + }); }; diff --git a/lib/cartodb/backends/user-limits.js b/lib/cartodb/backends/user-limits.js index 519f1cd1..2dc70470 100644 --- a/lib/cartodb/backends/user-limits.js +++ b/lib/cartodb/backends/user-limits.js @@ -1,5 +1,3 @@ -var step = require('step'); - /** * * @param metadataBackend @@ -41,45 +39,38 @@ UserLimitsBackend.prototype.getRenderLimits = function (username, apiKey, callba }; UserLimitsBackend.prototype.getTimeoutRenderLimit = function (username, apiKey, callback) { - var self = this; - - step( - function isAuthorized() { - var next = this; - - if (!apiKey) { - return next(null, false); - } - - self.metadataBackend.getUserMapKey(username, function (err, userApiKey) { - if (err) { - return next(err); - } - - return next(null, userApiKey === apiKey); - }); - }, - function getUserTimeoutRenderLimits(err, authorized) { - var next = this; + isAuthorized(this.metadataBackend, username, apiKey, (err, authorized) => { + if (err) { + return callback(err); + } + this.metadataBackend.getUserTimeoutRenderLimits(username, (err, timeoutRenderLimit) => { if (err) { - return next(err); + return callback(err); } - self.metadataBackend.getUserTimeoutRenderLimits(username, function (err, timeoutRenderLimit) { - if (err) { - return next(err); - } - - next(null, { - render: authorized ? timeoutRenderLimit.render : timeoutRenderLimit.renderPublic - }); - }); - }, - callback - ); + return callback( + null, + { render: authorized ? timeoutRenderLimit.render : timeoutRenderLimit.renderPublic } + ); + }); + }); }; +function isAuthorized(metadataBackend, username, apiKey, callback) { + if (!apiKey) { + return callback(null, false); + } + + metadataBackend.getUserMapKey(username, function (err, userApiKey) { + if (err) { + return callback(err); + } + + return callback(null, userApiKey === apiKey); + }); +} + UserLimitsBackend.prototype.preprareRateLimit = function () { if (this.options.limits.rateLimitsEnabled) { this.metadataBackend.loadRateLimitsScript();