Merge branch 'master' into turbo-carto-tokens
This commit is contained in:
commit
64dd033c94
12
NEWS.md
12
NEWS.md
@ -1,8 +1,18 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2.44.0
|
||||||
|
|
||||||
|
Released 2016-mm-dd
|
||||||
|
|
||||||
|
Adds support for sql wrap in all layers
|
||||||
|
|
||||||
|
|
||||||
## 2.43.1
|
## 2.43.1
|
||||||
|
|
||||||
Released 2016-mm-dd
|
Released 2016-05-19
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Dataview error when bbox present without query rewrite data #458
|
||||||
|
|
||||||
|
|
||||||
## 2.43.0
|
## 2.43.0
|
||||||
|
@ -139,17 +139,19 @@ DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, param
|
|||||||
if (params.bbox) {
|
if (params.bbox) {
|
||||||
var bboxFilter = new BBoxFilter({column: 'the_geom', srid: 4326}, {bbox: params.bbox});
|
var bboxFilter = new BBoxFilter({column: 'the_geom', srid: 4326}, {bbox: params.bbox});
|
||||||
query = bboxFilter.sql(query);
|
query = bboxFilter.sql(query);
|
||||||
var bbox_filter_definition = {
|
if ( queryRewriteData ) {
|
||||||
type: 'bbox',
|
var bbox_filter_definition = {
|
||||||
options: {
|
type: 'bbox',
|
||||||
column: 'the_geom',
|
options: {
|
||||||
srid: 4326,
|
column: 'the_geom',
|
||||||
},
|
srid: 4326,
|
||||||
params: {
|
},
|
||||||
bbox: params.bbox
|
params: {
|
||||||
}
|
bbox: params.bbox
|
||||||
};
|
}
|
||||||
queryRewriteData = _.extend(queryRewriteData, { bbox_filter: bbox_filter_definition });
|
};
|
||||||
|
queryRewriteData = _.extend(queryRewriteData, { bbox_filter: bbox_filter_definition });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var dataviewFactory = DataviewFactoryWithOverviews.getFactory(
|
var dataviewFactory = DataviewFactoryWithOverviews.getFactory(
|
||||||
|
@ -19,6 +19,7 @@ var MapConfigNamedLayersAdapter = require('../models/mapconfig_named_layers_adap
|
|||||||
var AnalysisMapConfigAdapter = require('../models/analysis-mapconfig-adapter');
|
var AnalysisMapConfigAdapter = require('../models/analysis-mapconfig-adapter');
|
||||||
var NamedMapMapConfigProvider = require('../models/mapconfig/named_map_provider');
|
var NamedMapMapConfigProvider = require('../models/mapconfig/named_map_provider');
|
||||||
var CreateLayergroupMapConfigProvider = require('../models/mapconfig/create_layergroup_provider');
|
var CreateLayergroupMapConfigProvider = require('../models/mapconfig/create_layergroup_provider');
|
||||||
|
var SqlWrapMapConfigAdapter = require('../models/mapconfig/adapter/sql-wrap-mapconfig-adapter');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {AuthApi} authApi
|
* @param {AuthApi} authApi
|
||||||
@ -52,6 +53,7 @@ function MapController(authApi, pgConnection, templateMaps, mapBackend, metadata
|
|||||||
this.analysisMapConfigAdapter = new AnalysisMapConfigAdapter(analysisBackend);
|
this.analysisMapConfigAdapter = new AnalysisMapConfigAdapter(analysisBackend);
|
||||||
this.namedLayersAdapter = new MapConfigNamedLayersAdapter(templateMaps);
|
this.namedLayersAdapter = new MapConfigNamedLayersAdapter(templateMaps);
|
||||||
this.overviewsAdapter = overviewsAdapter;
|
this.overviewsAdapter = overviewsAdapter;
|
||||||
|
this.sqlWrapMapConfigAdapter = new SqlWrapMapConfigAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
util.inherits(MapController, BaseController);
|
util.inherits(MapController, BaseController);
|
||||||
@ -139,6 +141,10 @@ MapController.prototype.create = function(req, res, prepareConfigFn) {
|
|||||||
self.req2params(req, this);
|
self.req2params(req, this);
|
||||||
},
|
},
|
||||||
prepareConfigFn,
|
prepareConfigFn,
|
||||||
|
function prepareSqlWrap(err, requestMapConfig) {
|
||||||
|
assert.ifError(err);
|
||||||
|
self.sqlWrapMapConfigAdapter.getMapConfig(requestMapConfig, this);
|
||||||
|
},
|
||||||
function prepareAnalysisLayers(err, requestMapConfig) {
|
function prepareAnalysisLayers(err, requestMapConfig) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
var analysisConfiguration = {
|
var analysisConfiguration = {
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
function SqlWrapMapConfigAdapter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SqlWrapMapConfigAdapter;
|
||||||
|
|
||||||
|
|
||||||
|
SqlWrapMapConfigAdapter.prototype.getMapConfig = function(requestMapConfig, callback) {
|
||||||
|
if (requestMapConfig && Array.isArray(requestMapConfig.layers)) {
|
||||||
|
requestMapConfig.layers = requestMapConfig.layers.map(function(layer) {
|
||||||
|
if (layer.options) {
|
||||||
|
var sqlQueryWrap = layer.options.sql_wrap;
|
||||||
|
if (sqlQueryWrap) {
|
||||||
|
var layerSql = layer.options.sql;
|
||||||
|
if (layerSql) {
|
||||||
|
layer.options.sql_raw = layerSql;
|
||||||
|
layer.options.sql = sqlQueryWrap.replace(/<%=\s*sql\s*%>/g, layerSql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return layer;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(null, requestMapConfig);
|
||||||
|
};
|
@ -6,6 +6,7 @@ var step = require('step');
|
|||||||
var MapConfig = require('windshaft').model.MapConfig;
|
var MapConfig = require('windshaft').model.MapConfig;
|
||||||
var templateName = require('../../backends/template_maps').templateName;
|
var templateName = require('../../backends/template_maps').templateName;
|
||||||
var QueryTables = require('cartodb-query-tables');
|
var QueryTables = require('cartodb-query-tables');
|
||||||
|
var SqlWrapMapConfigAdapter = require('./adapter/sql-wrap-mapconfig-adapter');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
@ -22,6 +23,7 @@ function NamedMapMapConfigProvider(templateMaps, pgConnection, metadataBackend,
|
|||||||
this.turboCartoAdapter = turboCartoAdapter;
|
this.turboCartoAdapter = turboCartoAdapter;
|
||||||
this.analysisMapConfigAdapter = analysisMapConfigAdapter;
|
this.analysisMapConfigAdapter = analysisMapConfigAdapter;
|
||||||
this.overviewsAdapter = overviewsAdapter;
|
this.overviewsAdapter = overviewsAdapter;
|
||||||
|
this.sqlWrapMapConfigAdapter = new SqlWrapMapConfigAdapter();
|
||||||
|
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.templateName = templateName(templateId);
|
this.templateName = templateName(templateId);
|
||||||
@ -95,6 +97,10 @@ NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) {
|
|||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
return self.templateMaps.instance(self.template, templateParams);
|
return self.templateMaps.instance(self.template, templateParams);
|
||||||
},
|
},
|
||||||
|
function prepareSqlWrap(err, requestMapConfig) {
|
||||||
|
assert.ifError(err);
|
||||||
|
self.sqlWrapMapConfigAdapter.getMapConfig(requestMapConfig, this);
|
||||||
|
},
|
||||||
function prepareAnalysisLayers(err, requestMapConfig) {
|
function prepareAnalysisLayers(err, requestMapConfig) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
var analysisConfiguration = {
|
var analysisConfiguration = {
|
||||||
|
2
npm-shrinkwrap.json
generated
2
npm-shrinkwrap.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "windshaft-cartodb",
|
"name": "windshaft-cartodb",
|
||||||
"version": "2.42.3",
|
"version": "2.44.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": {
|
"body-parser": {
|
||||||
"version": "1.14.2",
|
"version": "1.14.2",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "windshaft-cartodb",
|
"name": "windshaft-cartodb",
|
||||||
"version": "2.43.1",
|
"version": "2.44.0",
|
||||||
"description": "A map tile server for CartoDB",
|
"description": "A map tile server for CartoDB",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"cartodb"
|
"cartodb"
|
||||||
|
@ -58,6 +58,21 @@ describe('dataviews using tables without overviews', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should admit a bbox", function(done) {
|
||||||
|
var params = {
|
||||||
|
bbox: "-170,-80,170,80"
|
||||||
|
};
|
||||||
|
var testClient = new TestClient(nonOverviewsMapConfig);
|
||||||
|
testClient.getDataview('country_places_count', params, function(err, formula_result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.deepEqual(formula_result, { operation: 'count', result: 7253, nulls: 0, type: 'formula' });
|
||||||
|
|
||||||
|
testClient.drain(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('filters', function() {
|
describe('filters', function() {
|
||||||
|
|
||||||
describe('category', function () {
|
describe('category', function () {
|
||||||
@ -77,6 +92,23 @@ describe('dataviews using tables without overviews', function() {
|
|||||||
testClient.drain(done);
|
testClient.drain(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should expose a filtered formula and admit a bbox", function (done) {
|
||||||
|
var params = {
|
||||||
|
filters: {
|
||||||
|
dataviews: {country_categories: {accept: ['CAN']}}
|
||||||
|
},
|
||||||
|
bbox: "-170,-80,170,80"
|
||||||
|
};
|
||||||
|
var testClient = new TestClient(nonOverviewsMapConfig);
|
||||||
|
testClient.getDataview('country_places_count', params, function (err, formula_result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.deepEqual(formula_result, { operation: 'count', result: 254, nulls: 0, type: 'formula' });
|
||||||
|
testClient.drain(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -218,16 +250,32 @@ describe('dataviews using tables with overviews', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should admit a bbox", function(done) {
|
||||||
|
var params = {
|
||||||
|
bbox: "-170,-80,170,80"
|
||||||
|
};
|
||||||
|
var testClient = new TestClient(overviewsMapConfig);
|
||||||
|
testClient.getDataview('test_sum', params, function(err, formula_result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.deepEqual(formula_result, {"operation":"sum","result":15,"nulls":0,"type":"formula"});
|
||||||
|
|
||||||
|
testClient.drain(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('filters', function() {
|
describe('filters', function() {
|
||||||
|
|
||||||
describe('category', function () {
|
describe('category', function () {
|
||||||
|
|
||||||
it("should expose a filtered formula", function (done) {
|
var params = {
|
||||||
var params = {
|
filters: {
|
||||||
filters: {
|
dataviews: {test_categories: {accept: ['Hawai']}}
|
||||||
dataviews: {test_categories: {accept: ['Hawai']}}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
it("should expose a filtered sum formula", function (done) {
|
||||||
var testClient = new TestClient(overviewsMapConfig);
|
var testClient = new TestClient(overviewsMapConfig);
|
||||||
testClient.getDataview('test_sum', params, function (err, formula_result) {
|
testClient.getDataview('test_sum', params, function (err, formula_result) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -236,56 +284,74 @@ describe('dataviews using tables with overviews', function() {
|
|||||||
assert.deepEqual(formula_result, {"operation":"sum","result":1,"nulls":0,"type":"formula"});
|
assert.deepEqual(formula_result, {"operation":"sum","result":1,"nulls":0,"type":"formula"});
|
||||||
testClient.drain(done);
|
testClient.drain(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should expose an avg formula", function(done) {
|
|
||||||
var testClient = new TestClient(overviewsMapConfig);
|
|
||||||
testClient.getDataview('test_avg', { own_filter: 0 }, function(err, formula_result) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
assert.deepEqual(formula_result, {"operation":"avg","result":1,"nulls":0,"type":"formula"});
|
|
||||||
|
|
||||||
testClient.drain(done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should expose a count formula", function(done) {
|
|
||||||
var testClient = new TestClient(overviewsMapConfig);
|
|
||||||
testClient.getDataview('test_count', { own_filter: 0 }, function(err, formula_result) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
assert.deepEqual(formula_result, {"operation":"count","result":1,"nulls":0,"type":"formula"});
|
|
||||||
|
|
||||||
testClient.drain(done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should expose a max formula", function(done) {
|
|
||||||
var testClient = new TestClient(overviewsMapConfig);
|
|
||||||
testClient.getDataview('test_max', { own_filter: 0 }, function(err, formula_result) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
assert.deepEqual(formula_result, {"operation":"max","result":1,"nulls":0,"type":"formula"});
|
|
||||||
|
|
||||||
testClient.drain(done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should expose a min formula", function(done) {
|
|
||||||
var testClient = new TestClient(overviewsMapConfig);
|
|
||||||
testClient.getDataview('test_min', { own_filter: 0 }, function(err, formula_result) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
assert.deepEqual(formula_result, {"operation":"min","result":1,"nulls":0,"type":"formula"});
|
|
||||||
|
|
||||||
testClient.drain(done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should expose a filtered avg formula", function(done) {
|
||||||
|
var testClient = new TestClient(overviewsMapConfig);
|
||||||
|
testClient.getDataview('test_avg', params, function(err, formula_result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.deepEqual(formula_result, {"operation":"avg","result":1,"nulls":0,"type":"formula"});
|
||||||
|
|
||||||
|
testClient.drain(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should expose a filtered count formula", function(done) {
|
||||||
|
var testClient = new TestClient(overviewsMapConfig);
|
||||||
|
testClient.getDataview('test_count', params, function(err, formula_result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.deepEqual(formula_result, {"operation":"count","result":1,"nulls":0,"type":"formula"});
|
||||||
|
|
||||||
|
testClient.drain(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should expose a filterd max formula", function(done) {
|
||||||
|
var testClient = new TestClient(overviewsMapConfig);
|
||||||
|
testClient.getDataview('test_max', params, function(err, formula_result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.deepEqual(formula_result, {"operation":"max","result":1,"nulls":0,"type":"formula"});
|
||||||
|
|
||||||
|
testClient.drain(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should expose a filterd min formula", function(done) {
|
||||||
|
var testClient = new TestClient(overviewsMapConfig);
|
||||||
|
testClient.getDataview('test_min', params, function(err, formula_result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.deepEqual(formula_result, {"operation":"min","result":1,"nulls":0,"type":"formula"});
|
||||||
|
|
||||||
|
testClient.drain(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should expose a filtered sum formula with bbox", function (done) {
|
||||||
|
var bboxparams = {
|
||||||
|
filters: {
|
||||||
|
dataviews: {test_categories: {accept: ['Hawai']}}
|
||||||
|
},
|
||||||
|
bbox: "-170,-80,170,80"
|
||||||
|
};
|
||||||
|
var testClient = new TestClient(overviewsMapConfig);
|
||||||
|
testClient.getDataview('test_sum', bboxparams, function (err, formula_result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.deepEqual(formula_result, {"operation":"sum","result":1,"nulls":0,"type":"formula"});
|
||||||
|
testClient.drain(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
52
test/acceptance/sql-wrap.js
Normal file
52
test/acceptance/sql-wrap.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
require('../support/test_helper');
|
||||||
|
|
||||||
|
var assert = require('../support/assert');
|
||||||
|
var TestClient = require('../support/test-client');
|
||||||
|
|
||||||
|
describe('sql-wrap', function() {
|
||||||
|
|
||||||
|
afterEach(function(done) {
|
||||||
|
if (this.testClient) {
|
||||||
|
this.testClient.drain(done);
|
||||||
|
} else {
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use sql_wrap from layer options', function(done) {
|
||||||
|
var mapConfig = {
|
||||||
|
version: '1.5.0',
|
||||||
|
layers: [
|
||||||
|
{
|
||||||
|
"type": "cartodb",
|
||||||
|
"options": {
|
||||||
|
"sql": "SELECT * FROM populated_places_simple_reduced",
|
||||||
|
"sql_wrap": "SELECT * FROM (<%= sql %>) _w WHERE adm0_a3 = 'USA'",
|
||||||
|
"cartocss": [
|
||||||
|
"#points {",
|
||||||
|
" marker-fill-opacity: 1;",
|
||||||
|
" marker-line-color: #FFF;",
|
||||||
|
" marker-line-width: 0.5;",
|
||||||
|
" marker-line-opacity: 1;",
|
||||||
|
" marker-placement: point;",
|
||||||
|
" marker-type: ellipse;",
|
||||||
|
" marker-width: 8;",
|
||||||
|
" marker-fill: red;",
|
||||||
|
" marker-allow-overlap: true;",
|
||||||
|
"}"
|
||||||
|
].join('\n'),
|
||||||
|
"cartocss_version": "2.3.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
this.testClient = new TestClient(mapConfig, 1234);
|
||||||
|
this.testClient.getTile(0, 0, 0, function(err, tile, img) {
|
||||||
|
assert.ok(!err, err);
|
||||||
|
var fixtureImg = './test/fixtures/sql-wrap-usa-filter.png';
|
||||||
|
assert.imageIsSimilarToFile(img, fixtureImg, 20, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
BIN
test/fixtures/sql-wrap-usa-filter.png
vendored
Normal file
BIN
test/fixtures/sql-wrap-usa-filter.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
Loading…
Reference in New Issue
Block a user