diff --git a/lib/cartodb/cache/named_map_provider_cache.js b/lib/cartodb/cache/named_map_provider_cache.js index 1da6cf15..21c33142 100644 --- a/lib/cartodb/cache/named_map_provider_cache.js +++ b/lib/cartodb/cache/named_map_provider_cache.js @@ -1,6 +1,7 @@ var _ = require('underscore'); var dot = require('dot'); var NamedMapMapConfigProvider = require('../models/mapconfig/named_map_provider'); +var MapConfigNamedLayersAdapter = require('../models/mapconfig_named_layers_adapter'); var templateName = require('../backends/template_maps').templateName; var queue = require('queue-async'); @@ -12,6 +13,8 @@ function NamedMapProviderCache(templateMaps, pgConnection, userLimitsApi, queryT this.userLimitsApi = userLimitsApi; this.queryTablesApi = queryTablesApi; + this.namedLayersAdapter = new MapConfigNamedLayersAdapter(templateMaps); + this.providerCache = new LruCache({ max: 2000 }); } @@ -28,6 +31,7 @@ NamedMapProviderCache.prototype.get = function(user, templateId, config, authTok this.pgConnection, this.userLimitsApi, this.queryTablesApi, + this.namedLayersAdapter, user, templateId, config, diff --git a/lib/cartodb/controllers/map.js b/lib/cartodb/controllers/map.js index b72c7c1c..2254852c 100644 --- a/lib/cartodb/controllers/map.js +++ b/lib/cartodb/controllers/map.js @@ -195,6 +195,7 @@ MapController.prototype.instantiateTemplate = function(req, res, prepareParamsFn self.pgConnection, self.userLimitsApi, self.queryTablesApi, + self.namedLayersAdapter, cdbuser, req.params.template_id, templateParams, diff --git a/lib/cartodb/models/mapconfig/named_map_provider.js b/lib/cartodb/models/mapconfig/named_map_provider.js index cea4ff39..0c86ce29 100644 --- a/lib/cartodb/models/mapconfig/named_map_provider.js +++ b/lib/cartodb/models/mapconfig/named_map_provider.js @@ -10,12 +10,14 @@ var templateName = require('../../backends/template_maps').templateName; * @constructor * @type {NamedMapMapConfigProvider} */ -function NamedMapMapConfigProvider(templateMaps, pgConnection, userLimitsApi, queryTablesApi, +function NamedMapMapConfigProvider(templateMaps, pgConnection, userLimitsApi, queryTablesApi, namedLayersAdapter, owner, templateId, config, authToken, params) { this.templateMaps = templateMaps; this.pgConnection = pgConnection; this.userLimitsApi = userLimitsApi; this.queryTablesApi = queryTablesApi; + this.namedLayersAdapter = namedLayersAdapter; + this.owner = owner; this.templateName = templateName(templateId); this.config = config; @@ -46,6 +48,7 @@ NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) { var self = this; var mapConfig = null; + var datasource = null; var rendererParams; step( @@ -72,9 +75,26 @@ NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) { assert.ifError(err); return self.templateMaps.instance(self.template, templateParams); }, - function prepareLayergroup(err, layergroup) { + function prepareLayergroup(err, _mapConfig) { assert.ifError(err); - mapConfig = layergroup; + var next = this; + self.namedLayersAdapter.getLayers(self.owner, _mapConfig.layers, self.pgConnection, + function(err, layers, datasource) { + if (err) { + return next(err); + } + + if (layers) { + _mapConfig.layers = layers; + } + return next(null, _mapConfig, datasource); + } + ); + }, + function beforeLayergroupCreate(err, _mapConfig, _datasource) { + assert.ifError(err); + mapConfig = _mapConfig; + datasource = _datasource; rendererParams = _.extend({}, self.params, { user: self.owner }); @@ -86,7 +106,7 @@ NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) { }, function cacheAndReturnMapConfig(err, renderLimits) { self.err = err; - self.mapConfig = (mapConfig === null) ? null : MapConfig.create(mapConfig); + self.mapConfig = (mapConfig === null) ? null : new MapConfig(mapConfig, datasource); self.rendererParams = rendererParams; self.context.limits = renderLimits || {}; return callback(self.err, self.mapConfig, self.rendererParams, self.context); diff --git a/test/acceptance/named_layers.js b/test/acceptance/named_layers.js index 71f8ea44..d59d8da8 100644 --- a/test/acceptance/named_layers.js +++ b/test/acceptance/named_layers.js @@ -435,7 +435,7 @@ describe('named_layers', function() { }, function deleteTemplate(err) { var next = this; - templateMaps.delTemplate(username, privateTableTemplate, function(/*delErr*/) { + templateMaps.delTemplate(username, privateTableTemplateName, function(/*delErr*/) { // ignore deletion error next(err); }); @@ -563,7 +563,7 @@ describe('named_layers', function() { }, function deleteTemplate(err) { var next = this; - templateMaps.delTemplate(username, privateTableTemplate, function(/*delErr*/) { + templateMaps.delTemplate(username, privateTableTemplateNameInteractivity, function(/*delErr*/) { // ignore deletion error next(err); }); @@ -717,6 +717,117 @@ describe('named_layers', function() { }); + it('should work with named tiles', function(done) { + + var namedTilesTemplateName = 'named_tiles_template'; + var namedTilesTemplate = { + version: '0.0.1', + name: namedTilesTemplateName, + auth: { + method: 'open' + }, + layergroup: { + layers: [ + namedMapLayer, + { + type: 'mapnik', + options: { + sql: 'select * from test_table_private_1', + cartocss: '#layer { marker-fill: #cc3300; }', + cartocss_version: '2.3.0' + } + } + ] + } + }; + + step( + function createTemplate() { + templateMaps.addTemplate(username, namedTilesTemplate, this); + }, + function createLayergroup(err) { + if (err) { + throw err; + } + + var next = this; + assert.response(server, + { + url: '/api/v1/map/named/' + namedTilesTemplateName + '?api_key=1234', + method: 'POST', + headers: { + host: 'localhost', + 'Content-Type': 'application/json' + } + }, + { + status: 200 + }, + function(res, err) { + next(err, res); + } + ); + }, + function checkLayergroup(err, response) { + if (err) { + throw err; + } + + var parsedBody = JSON.parse(response.body); + assert.ok(parsedBody.layergroupid); + assert.ok(parsedBody.last_updated); + + assert.equal(parsedBody.metadata.layers[0].type, 'mapnik'); + assert.equal(parsedBody.metadata.layers[1].type, 'mapnik'); + + return parsedBody.layergroupid; + }, + function requestTile(err, layergroupId) { + if (err) { + throw err; + } + + var next = this; + assert.response(server, + { + url: '/api/v1/map/' + layergroupId + '/all/0/0/0.png', + method: 'GET', + headers: { + host: 'localhost' + }, + encoding: 'binary' + }, + { + status: 200, + headers: { + 'content-type': 'image/png' + } + }, + function(res, err) { + next(err, res); + } + ); + }, + function handleTileResponse(err, res) { + if (err) { + throw err; + } + test_helper.checkCache(res); + return true; + }, + function deleteTemplate(err) { + var next = this; + templateMaps.delTemplate(username, namedTilesTemplateName, function(/*delErr*/) { + // ignore deletion error + next(err); + }); + }, + function finish(err) { + done(err); + } + ); + + }); after(function(done) { global.environment.enabledFeatures = {cdbQueryTablesFromPostgres: false};