Merge branch 'master' into upgrade-camshaft-to-avoid-missing-columns

This commit is contained in:
Daniel García Aubert 2018-08-02 16:42:09 +02:00
commit 9a3bd51664
7 changed files with 400 additions and 349 deletions

View File

@ -5,6 +5,8 @@ Released 2018-mm-dd
- Upgrades Camshaft to [0.62.2](https://github.com/CartoDB/camshaft/releases/tag/0.61.11):
- Build query from node's cache to compute output columns when building analysis
- Remove use of `step` module to handle asynchronous code, now it's defined as development dependency.
## 6.3.0
Released 2018-07-26

View File

@ -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];

View File

@ -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);
});
});
};

View File

@ -1,7 +1,5 @@
var assert = require('assert');
var crypto = require('crypto');
var debug = require('debug')('windshaft:templates');
var step = require('step');
var _ = require('underscore');
var dot = require('dot');
@ -69,27 +67,19 @@ TemplateMaps.prototype._userTemplateLimit = function() {
* @param callback - function to pass results too.
*/
TemplateMaps.prototype._redisCmd = function(redisFunc, redisArgs, callback) {
var redisClient;
var that = this;
var db = that.db_signatures;
this.redis_pool.acquire(this.db_signatures, (err, redisClient) => {
if (err) {
return callback(err);
}
step(
function getRedisClient() {
that.redis_pool.acquire(db, this);
},
function executeQuery(err, data) {
assert.ifError(err);
redisClient = data;
redisArgs.push(this);
redisClient[redisFunc.toUpperCase()].apply(redisClient, redisArgs);
},
function releaseRedisClient(err, data) {
if ( ! _.isUndefined(redisClient) ) {
that.redis_pool.release(db, redisClient);
}
callback(err, data);
}
);
redisClient[redisFunc.toUpperCase()](...redisArgs, (err, data) => {
this.redis_pool.release(this.db_signatures, redisClient);
if (err) {
return callback(err);
}
return callback(null, data);
});
});
};
var _reValidNameIdentifier = /^[a-z0-9][0-9a-z_\-]*$/i;
@ -184,6 +174,37 @@ function templateDefaults(template) {
});
}
/**
* Checks if the if the user reaches the templetes limit
*
* @param userTemplatesKey user templat key in Redis
* @param owner cartodb username of the template owner
* @param callback returns error if the user reaches the limit
*/
TemplateMaps.prototype._checkUserTemplatesLimit = function(userTemplatesKey, owner, callback) {
const limit = this._userTemplateLimit();
if(!limit) {
return callback();
}
this._redisCmd('HLEN', [userTemplatesKey], (err, numberOfTemplates) => {
if (err) {
return callback(err);
}
if (numberOfTemplates >= limit) {
const limitReachedError = new Error(
`User '${owner}' reached limit on number of templates (${numberOfTemplates}/${limit})`
);
limitReachedError.http_status = 409;
return callback(limitReachedError);
}
return callback();
});
};
//--------------- PUBLIC API -------------------------------------
// Add a template
@ -199,52 +220,41 @@ function templateDefaults(template) {
// Return template identifier (only valid for given user)
//
TemplateMaps.prototype.addTemplate = function(owner, template, callback) {
var self = this;
template = templateDefaults(template);
var invalidError = this._checkInvalidTemplate(template);
if ( invalidError ) {
if (invalidError) {
return callback(invalidError);
}
var templateName = template.name;
var userTemplatesKey = this.key_usr_tpl({ owner:owner });
var limit = this._userTemplateLimit();
var userTemplatesKey = this.key_usr_tpl({ owner });
step(
function checkLimit() {
if ( ! limit ) {
return 0;
}
self._redisCmd('HLEN', [ userTemplatesKey ], this);
},
function installTemplateIfDoesNotExist(err, numberOfTemplates) {
assert.ifError(err);
if ( limit && numberOfTemplates >= limit ) {
var limitReachedError = new Error("User '" + owner + "' reached limit on number of templates (" +
numberOfTemplates + "/" + limit + ")");
limitReachedError.http_status = 409;
throw limitReachedError;
}
self._redisCmd('HSETNX', [ userTemplatesKey, templateName, JSON.stringify(template) ], this);
},
function validateInstallation(err, wasSet) {
assert.ifError(err);
if ( ! wasSet ) {
throw new Error("Template '" + templateName + "' of user '" + owner + "' already exists");
}
return true;
},
function finish(err) {
if (!err) {
self.emit('add', owner, templateName, template);
}
callback(err, templateName, template);
this._checkUserTemplatesLimit(userTemplatesKey, owner, err => {
if (err) {
return callback(err);
}
);
let templateString;
try {
templateString = JSON.stringify(template);
} catch (error) {
return callback(error);
}
this._redisCmd('HSETNX', [userTemplatesKey, template.name, templateString], (err, wasSet) => {
if (err) {
return callback(err);
}
if (!wasSet) {
var templateExistsError = new Error(`Template '${template.name}' of user '${owner}' already exists`);
return callback(templateExistsError);
}
this.emit('add', owner, template.name, template);
return callback(null, template.name, template);
});
});
};
// Delete a template
@ -257,26 +267,18 @@ TemplateMaps.prototype.addTemplate = function(owner, template, callback) {
// @param callback function(err)
//
TemplateMaps.prototype.delTemplate = function(owner, tpl_id, callback) {
var self = this;
step(
function deleteTemplate() {
self._redisCmd('HDEL', [ self.key_usr_tpl({ owner:owner }), tpl_id ], this);
},
function handleDeletion(err, deleted) {
assert.ifError(err);
if (!deleted) {
throw new Error("Template '" + tpl_id + "' of user '" + owner + "' does not exist");
}
return true;
},
function finish(err) {
if (!err) {
self.emit('delete', owner, tpl_id);
}
callback(err);
this._redisCmd('HDEL', [ this.key_usr_tpl({ owner:owner }), tpl_id ], (err, deleted) => {
if (err) {
return callback(err);
}
);
if (!deleted) {
return callback(new Error(`Template '${tpl_id}' of user '${owner}' does not exist`));
}
this.emit('delete', owner, tpl_id);
return callback();
});
};
// Update a template
@ -296,56 +298,58 @@ TemplateMaps.prototype.delTemplate = function(owner, tpl_id, callback) {
// @param callback function(err)
//
TemplateMaps.prototype.updTemplate = function(owner, tpl_id, template, callback) {
var self = this;
template = templateDefaults(template);
var invalidError = this._checkInvalidTemplate(template);
if ( invalidError ) {
if (invalidError) {
return callback(invalidError);
}
var templateName = template.name;
if ( tpl_id !== templateName ) {
return callback(new Error("Cannot update name of a map template ('" + tpl_id + "' != '" + templateName + "')"));
if (tpl_id !== template.name) {
return callback(new Error(`Cannot update name of a map template ('${tpl_id}' != '${template.name}')`));
}
var userTemplatesKey = this.key_usr_tpl({ owner:owner });
var userTemplatesKey = this.key_usr_tpl({ owner });
var previousTemplate = null;
this._redisCmd('HGET', [userTemplatesKey, tpl_id], (err, beforeUpdateTemplate) => {
if (err) {
return callback(err);
}
step(
function getExistingTemplate() {
self._redisCmd('HGET', [ userTemplatesKey, tpl_id ], this);
},
function updateTemplate(err, _currentTemplate) {
assert.ifError(err);
if (!_currentTemplate) {
throw new Error("Template '" + tpl_id + "' of user '" + owner + "' does not exist");
if (!beforeUpdateTemplate) {
return callback(new Error(`Template '${tpl_id}' of user '${owner}' does not exist`));
}
let templateString;
try {
templateString = JSON.stringify(template);
} catch (error) {
return callback(error);
}
this._redisCmd('HSET', [userTemplatesKey, template.name, templateString], (err, didSetNewField) => {
if (err) {
return callback(err);
}
previousTemplate = _currentTemplate;
self._redisCmd('HSET', [ userTemplatesKey, templateName, JSON.stringify(template) ], this);
},
function handleTemplateUpdate(err, didSetNewField) {
assert.ifError(err);
if (didSetNewField) {
debug('New template created on update operation');
}
return true;
},
function finish(err) {
if (!err) {
if (self.fingerPrint(JSON.parse(previousTemplate)) !== self.fingerPrint(template)) {
self.emit('update', owner, templateName, template);
}
let beforeUpdateTemplateObject;
try {
beforeUpdateTemplateObject = JSON.parse(beforeUpdateTemplate);
} catch (error) {
return callback(error);
}
callback(err, template);
}
);
if (this.fingerPrint(beforeUpdateTemplateObject) !== this.fingerPrint(template)) {
this.emit('update', owner, template.name, template);
}
return callback(null, template);
});
});
};
// List user templates
@ -370,19 +374,20 @@ TemplateMaps.prototype.listTemplates = function(owner, callback) {
// Return full template definition
//
TemplateMaps.prototype.getTemplate = function(owner, tpl_id, callback) {
var self = this;
step(
function getTemplate() {
self._redisCmd('HGET', [ self.key_usr_tpl({owner:owner}), tpl_id ], this);
},
function parseTemplate(err, tpl_val) {
assert.ifError(err);
return JSON.parse(tpl_val);
},
function finish(err, tpl) {
callback(err, tpl);
this._redisCmd('HGET', [this.key_usr_tpl({owner:owner}), tpl_id], (err, template) => {
if (err) {
return callback(err);
}
);
let templateObject;
try {
templateObject = JSON.parse(template);
} catch (error) {
return callback(error);
}
return callback(null, templateObject);
});
};
TemplateMaps.prototype.isAuthorized = function(template, authTokens) {

View File

@ -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();

View File

@ -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 };
}

View File

@ -45,7 +45,6 @@
"redis-mpool": "0.5.0",
"request": "2.87.0",
"semver": "5.5.0",
"step": "1.0.0",
"step-profiler": "0.3.0",
"turbo-carto": "0.20.4",
"underscore": "1.6.0",
@ -59,6 +58,7 @@
"moment": "2.22.1",
"nock": "9.2.6",
"redis": "2.8.0",
"step": "1.0.0",
"strftime": "0.10.0"
},
"scripts": {