2015-07-10 17:24:32 +08:00
|
|
|
var assert = require('assert');
|
|
|
|
var step = require('step');
|
|
|
|
|
2015-09-16 22:18:26 +08:00
|
|
|
var util = require('util');
|
|
|
|
var BaseController = require('./base');
|
|
|
|
|
2015-07-10 17:24:32 +08:00
|
|
|
var cors = require('../middleware/cors');
|
2015-09-30 23:17:01 +08:00
|
|
|
var userMiddleware = require('../middleware/user');
|
2015-07-10 17:24:32 +08:00
|
|
|
|
2016-03-19 00:22:02 +08:00
|
|
|
var DataviewBackend = require('../backends/dataview');
|
2016-04-14 19:25:56 +08:00
|
|
|
var AnalysisStatusBackend = require('../backends/analysis-status');
|
2016-03-19 00:22:02 +08:00
|
|
|
|
2015-07-10 18:31:56 +08:00
|
|
|
var MapStoreMapConfigProvider = require('../models/mapconfig/map_store_provider');
|
2016-02-22 18:40:25 +08:00
|
|
|
|
2016-02-23 02:11:54 +08:00
|
|
|
var QueryTables = require('cartodb-query-tables');
|
2015-07-10 17:24:32 +08:00
|
|
|
|
|
|
|
/**
|
2015-09-16 22:18:26 +08:00
|
|
|
* @param {AuthApi} authApi
|
|
|
|
* @param {PgConnection} pgConnection
|
2015-07-10 17:24:32 +08:00
|
|
|
* @param {MapStore} mapStore
|
|
|
|
* @param {TileBackend} tileBackend
|
|
|
|
* @param {PreviewBackend} previewBackend
|
|
|
|
* @param {AttributesBackend} attributesBackend
|
2015-10-26 17:23:56 +08:00
|
|
|
* @param {WidgetBackend} widgetBackend
|
2015-07-14 19:40:41 +08:00
|
|
|
* @param {SurrogateKeysCache} surrogateKeysCache
|
2015-07-14 17:55:49 +08:00
|
|
|
* @param {UserLimitsApi} userLimitsApi
|
2015-07-14 19:40:41 +08:00
|
|
|
* @param {LayergroupAffectedTables} layergroupAffectedTables
|
2016-04-14 23:09:07 +08:00
|
|
|
* @param {AnalysisBackend} analysisBackend
|
2015-07-10 17:24:32 +08:00
|
|
|
* @constructor
|
|
|
|
*/
|
2015-10-01 00:00:54 +08:00
|
|
|
function LayergroupController(authApi, pgConnection, mapStore, tileBackend, previewBackend, attributesBackend,
|
2016-04-14 23:09:07 +08:00
|
|
|
widgetBackend, surrogateKeysCache, userLimitsApi, layergroupAffectedTables, analysisBackend) {
|
2015-09-16 22:18:26 +08:00
|
|
|
BaseController.call(this, authApi, pgConnection);
|
|
|
|
|
2016-02-22 18:40:25 +08:00
|
|
|
this.pgConnection = pgConnection;
|
2015-07-10 17:24:32 +08:00
|
|
|
this.mapStore = mapStore;
|
|
|
|
this.tileBackend = tileBackend;
|
|
|
|
this.previewBackend = previewBackend;
|
|
|
|
this.attributesBackend = attributesBackend;
|
2015-10-26 17:23:56 +08:00
|
|
|
this.widgetBackend = widgetBackend;
|
2015-07-14 19:40:41 +08:00
|
|
|
this.surrogateKeysCache = surrogateKeysCache;
|
2015-07-11 01:10:55 +08:00
|
|
|
this.userLimitsApi = userLimitsApi;
|
2015-07-14 19:40:41 +08:00
|
|
|
this.layergroupAffectedTables = layergroupAffectedTables;
|
2016-03-19 00:22:02 +08:00
|
|
|
|
2016-04-14 23:09:07 +08:00
|
|
|
this.dataviewBackend = new DataviewBackend(analysisBackend);
|
2016-04-14 19:25:56 +08:00
|
|
|
this.analysisStatusBackend = new AnalysisStatusBackend();
|
2015-07-10 17:24:32 +08:00
|
|
|
}
|
|
|
|
|
2015-09-16 22:18:26 +08:00
|
|
|
util.inherits(LayergroupController, BaseController);
|
|
|
|
|
2015-07-10 17:24:32 +08:00
|
|
|
module.exports = LayergroupController;
|
|
|
|
|
|
|
|
|
|
|
|
LayergroupController.prototype.register = function(app) {
|
2015-09-30 23:17:01 +08:00
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/:token/:z/:x/:y@:scale_factor?x.:format', cors(), userMiddleware,
|
|
|
|
this.tile.bind(this));
|
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/:token/:z/:x/:y.:format', cors(), userMiddleware,
|
|
|
|
this.tile.bind(this));
|
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/:token/:layer/:z/:x/:y.(:format)', cors(), userMiddleware,
|
|
|
|
this.layer.bind(this));
|
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/:token/:layer/attributes/:fid', cors(), userMiddleware,
|
|
|
|
this.attributes.bind(this));
|
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/static/center/:token/:z/:lat/:lng/:width/:height.:format', cors(), userMiddleware,
|
2015-07-10 17:24:32 +08:00
|
|
|
this.center.bind(this));
|
2015-09-30 23:17:01 +08:00
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/static/bbox/:token/:west,:south,:east,:north/:width/:height.:format', cors(), userMiddleware,
|
2015-07-10 17:24:32 +08:00
|
|
|
this.bbox.bind(this));
|
2015-10-07 01:47:44 +08:00
|
|
|
|
2016-01-16 00:02:09 +08:00
|
|
|
// Undocumented/non-supported API endpoint methods.
|
|
|
|
// Use at your own peril.
|
2015-10-07 01:47:44 +08:00
|
|
|
app.get(app.base_url_mapconfig +
|
2015-10-26 20:42:06 +08:00
|
|
|
'/:token/:layer/widget/:widgetName', cors(), userMiddleware,
|
|
|
|
this.widget.bind(this));
|
2015-11-16 20:15:01 +08:00
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/:token/:layer/widget/:widgetName/search', cors(), userMiddleware,
|
|
|
|
this.widgetSearch.bind(this));
|
2016-03-19 00:22:02 +08:00
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/:token/dataview/:dataviewName', cors(), userMiddleware,
|
|
|
|
this.dataview.bind(this));
|
2016-03-23 19:14:17 +08:00
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
|
|
|
'/:token/dataview/:dataviewName/search', cors(), userMiddleware,
|
|
|
|
this.dataviewSearch.bind(this));
|
2016-04-12 00:49:56 +08:00
|
|
|
|
|
|
|
app.get(app.base_url_mapconfig +
|
2016-04-14 17:08:39 +08:00
|
|
|
'/:token/analysis/node/:nodeId', cors(), userMiddleware,
|
2016-04-12 00:49:56 +08:00
|
|
|
this.analysisNodeStatus.bind(this));
|
|
|
|
};
|
|
|
|
|
|
|
|
LayergroupController.prototype.analysisNodeStatus = function(req, res) {
|
2016-04-14 16:59:51 +08:00
|
|
|
var self = this;
|
|
|
|
|
|
|
|
step(
|
|
|
|
function setupParams() {
|
|
|
|
self.req2params(req, this);
|
|
|
|
},
|
|
|
|
function retrieveNodeStatus(err) {
|
|
|
|
assert.ifError(err);
|
2016-04-14 19:25:56 +08:00
|
|
|
self.analysisStatusBackend.getNodeStatus(req.params, this);
|
2016-04-14 16:59:51 +08:00
|
|
|
},
|
|
|
|
function finish(err, nodeStatus, stats) {
|
|
|
|
req.profiler.add(stats || {});
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
self.sendError(req, res, err, 'GET NODE STATUS');
|
|
|
|
} else {
|
|
|
|
self.sendResponse(req, res, nodeStatus, 200);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2016-03-19 00:22:02 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
LayergroupController.prototype.dataview = function(req, res) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
step(
|
|
|
|
function setupParams() {
|
|
|
|
self.req2params(req, this);
|
|
|
|
},
|
2016-03-23 19:14:17 +08:00
|
|
|
function retrieveDataview(err) {
|
2016-03-19 00:22:02 +08:00
|
|
|
assert.ifError(err);
|
|
|
|
|
|
|
|
var mapConfigProvider = new MapStoreMapConfigProvider(
|
|
|
|
self.mapStore, req.context.user, self.userLimitsApi, req.params
|
|
|
|
);
|
|
|
|
self.dataviewBackend.getDataview(mapConfigProvider, req.context.user, req.params, this);
|
|
|
|
},
|
2016-04-14 01:15:06 +08:00
|
|
|
function finish(err, dataview, stats) {
|
2016-03-19 00:22:02 +08:00
|
|
|
req.profiler.add(stats || {});
|
|
|
|
|
|
|
|
if (err) {
|
2016-03-23 19:14:17 +08:00
|
|
|
self.sendError(req, res, err, 'GET DATAVIEW');
|
|
|
|
} else {
|
2016-04-14 01:15:06 +08:00
|
|
|
self.sendResponse(req, res, dataview, 200);
|
2016-03-23 19:14:17 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
LayergroupController.prototype.dataviewSearch = function(req, res) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
step(
|
|
|
|
function setupParams() {
|
|
|
|
self.req2params(req, this);
|
|
|
|
},
|
|
|
|
function searchDataview(err) {
|
|
|
|
assert.ifError(err);
|
|
|
|
|
|
|
|
var mapConfigProvider = new MapStoreMapConfigProvider(
|
|
|
|
self.mapStore, req.context.user, self.userLimitsApi, req.params
|
|
|
|
);
|
|
|
|
self.dataviewBackend.search(mapConfigProvider, req.context.user, req.params, this);
|
|
|
|
},
|
2016-04-14 01:15:06 +08:00
|
|
|
function finish(err, searchResult, stats) {
|
2016-03-23 19:14:17 +08:00
|
|
|
req.profiler.add(stats || {});
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
self.sendError(req, res, err, 'GET DATAVIEW SEARCH');
|
2016-03-19 00:22:02 +08:00
|
|
|
} else {
|
2016-04-14 01:15:06 +08:00
|
|
|
self.sendResponse(req, res, searchResult, 200);
|
2016-03-19 00:22:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2015-07-10 17:24:32 +08:00
|
|
|
};
|
|
|
|
|
2015-10-26 20:42:06 +08:00
|
|
|
LayergroupController.prototype.widget = function(req, res) {
|
2015-10-26 18:10:59 +08:00
|
|
|
var self = this;
|
|
|
|
|
|
|
|
step(
|
|
|
|
function setupParams() {
|
|
|
|
self.req2params(req, this);
|
|
|
|
},
|
|
|
|
function retrieveList(err) {
|
|
|
|
assert.ifError(err);
|
|
|
|
|
|
|
|
var mapConfigProvider = new MapStoreMapConfigProvider(
|
|
|
|
self.mapStore, req.context.user, self.userLimitsApi, req.params
|
|
|
|
);
|
2015-10-26 20:42:06 +08:00
|
|
|
self.widgetBackend.getWidget(mapConfigProvider, req.params, this);
|
2015-10-26 18:10:59 +08:00
|
|
|
},
|
2016-04-14 01:15:06 +08:00
|
|
|
function finish(err, widget, stats) {
|
2015-10-26 18:10:59 +08:00
|
|
|
req.profiler.add(stats || {});
|
|
|
|
|
|
|
|
if (err) {
|
2015-10-26 20:42:06 +08:00
|
|
|
self.sendError(req, res, err, 'GET WIDGET');
|
2015-10-26 18:10:59 +08:00
|
|
|
} else {
|
2016-04-14 01:15:06 +08:00
|
|
|
self.sendResponse(req, res, widget, 200);
|
2015-10-26 18:10:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2015-11-16 20:15:01 +08:00
|
|
|
LayergroupController.prototype.widgetSearch = function(req, res) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
step(
|
|
|
|
function setupParams() {
|
|
|
|
self.req2params(req, this);
|
|
|
|
},
|
|
|
|
function retrieveList(err) {
|
|
|
|
assert.ifError(err);
|
|
|
|
|
|
|
|
var mapConfigProvider = new MapStoreMapConfigProvider(
|
|
|
|
self.mapStore, req.context.user, self.userLimitsApi, req.params
|
|
|
|
);
|
|
|
|
self.widgetBackend.search(mapConfigProvider, req.params, this);
|
|
|
|
},
|
2016-04-14 01:15:06 +08:00
|
|
|
function finish(err, searchResult, stats) {
|
2015-11-16 20:15:01 +08:00
|
|
|
req.profiler.add(stats || {});
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
self.sendError(req, res, err, 'GET WIDGET');
|
|
|
|
} else {
|
2016-04-14 01:15:06 +08:00
|
|
|
self.sendResponse(req, res, searchResult, 200);
|
2015-11-16 20:15:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2015-07-10 17:24:32 +08:00
|
|
|
LayergroupController.prototype.attributes = function(req, res) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
req.profiler.start('windshaft.maplayer_attribute');
|
|
|
|
|
|
|
|
step(
|
|
|
|
function setupParams() {
|
2015-09-16 22:18:26 +08:00
|
|
|
self.req2params(req, this);
|
2015-07-10 17:24:32 +08:00
|
|
|
},
|
|
|
|
function retrieveFeatureAttributes(err) {
|
|
|
|
assert.ifError(err);
|
|
|
|
|
2015-09-15 00:46:22 +08:00
|
|
|
var mapConfigProvider = new MapStoreMapConfigProvider(
|
|
|
|
self.mapStore, req.context.user, self.userLimitsApi, req.params
|
|
|
|
);
|
|
|
|
self.attributesBackend.getFeatureAttributes(mapConfigProvider, req.params, false, this);
|
2015-07-10 17:24:32 +08:00
|
|
|
},
|
|
|
|
function finish(err, tile, stats) {
|
|
|
|
req.profiler.add(stats || {});
|
|
|
|
|
|
|
|
if (err) {
|
2015-09-17 03:54:56 +08:00
|
|
|
self.sendError(req, res, err, 'GET ATTRIBUTES');
|
2015-07-10 17:24:32 +08:00
|
|
|
} else {
|
2015-09-17 08:05:25 +08:00
|
|
|
self.sendResponse(req, res, tile, 200);
|
2015-07-10 17:24:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// Gets a tile for a given token and set of tile ZXY coords. (OSM style)
|
|
|
|
LayergroupController.prototype.tile = function(req, res) {
|
|
|
|
req.profiler.start('windshaft.map_tile');
|
|
|
|
this.tileOrLayer(req, res);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Gets a tile for a given token, layer set of tile ZXY coords. (OSM style)
|
|
|
|
LayergroupController.prototype.layer = function(req, res, next) {
|
|
|
|
if (req.params.token === 'static') {
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
req.profiler.start('windshaft.maplayer_tile');
|
|
|
|
this.tileOrLayer(req, res);
|
|
|
|
};
|
|
|
|
|
|
|
|
LayergroupController.prototype.tileOrLayer = function (req, res) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
step(
|
|
|
|
function mapController$prepareParams() {
|
2015-09-16 22:18:26 +08:00
|
|
|
self.req2params(req, this);
|
2015-07-10 17:24:32 +08:00
|
|
|
},
|
|
|
|
function mapController$getTileOrGrid(err) {
|
2015-09-16 00:16:50 +08:00
|
|
|
assert.ifError(err);
|
2015-07-11 01:10:55 +08:00
|
|
|
self.tileBackend.getTile(
|
|
|
|
new MapStoreMapConfigProvider(self.mapStore, req.context.user, self.userLimitsApi, req.params),
|
|
|
|
req.params, this
|
|
|
|
);
|
2015-07-10 17:24:32 +08:00
|
|
|
},
|
|
|
|
function mapController$finalize(err, tile, headers, stats) {
|
|
|
|
req.profiler.add(stats);
|
|
|
|
self.finalizeGetTileOrGrid(err, req, res, tile, headers);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
// This function is meant for being called as the very last
|
|
|
|
// step by all endpoints serving tiles or grids
|
|
|
|
LayergroupController.prototype.finalizeGetTileOrGrid = function(err, req, res, tile, headers) {
|
|
|
|
var supportedFormats = {
|
|
|
|
grid_json: true,
|
|
|
|
json_torque: true,
|
|
|
|
torque_json: true,
|
|
|
|
png: true
|
|
|
|
};
|
|
|
|
|
|
|
|
var formatStat = 'invalid';
|
|
|
|
if (req.params.format) {
|
|
|
|
var format = req.params.format.replace('.', '_');
|
|
|
|
if (supportedFormats[format]) {
|
|
|
|
formatStat = format;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-16 07:36:51 +08:00
|
|
|
if (err) {
|
2015-07-10 17:24:32 +08:00
|
|
|
// See https://github.com/Vizzuality/Windshaft-cartodb/issues/68
|
|
|
|
var errMsg = err.message ? ( '' + err.message ) : ( '' + err );
|
|
|
|
|
|
|
|
// Rewrite mapnik parsing errors to start with layer number
|
|
|
|
var matches = errMsg.match("(.*) in style 'layer([0-9]+)'");
|
|
|
|
if (matches) {
|
|
|
|
errMsg = 'style'+matches[2]+': ' + matches[1];
|
|
|
|
}
|
2015-09-16 07:36:51 +08:00
|
|
|
err.message = errMsg;
|
2015-07-10 17:24:32 +08:00
|
|
|
|
2015-09-17 03:54:56 +08:00
|
|
|
this.sendError(req, res, err, 'TILE RENDER');
|
2015-07-10 17:24:32 +08:00
|
|
|
global.statsClient.increment('windshaft.tiles.error');
|
|
|
|
global.statsClient.increment('windshaft.tiles.' + formatStat + '.error');
|
|
|
|
} else {
|
2015-09-17 08:05:25 +08:00
|
|
|
this.sendResponse(req, res, tile, 200, headers);
|
2015-07-10 17:24:32 +08:00
|
|
|
global.statsClient.increment('windshaft.tiles.success');
|
|
|
|
global.statsClient.increment('windshaft.tiles.' + formatStat + '.success');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
LayergroupController.prototype.bbox = function(req, res) {
|
|
|
|
this.staticMap(req, res, +req.params.width, +req.params.height, {
|
|
|
|
west: +req.params.west,
|
|
|
|
north: +req.params.north,
|
|
|
|
east: +req.params.east,
|
|
|
|
south: +req.params.south
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
LayergroupController.prototype.center = function(req, res) {
|
|
|
|
this.staticMap(req, res, +req.params.width, +req.params.height, +req.params.z, {
|
|
|
|
lng: +req.params.lng,
|
|
|
|
lat: +req.params.lat
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
LayergroupController.prototype.staticMap = function(req, res, width, height, zoom /* bounds */, center) {
|
|
|
|
var format = req.params.format === 'jpg' ? 'jpeg' : 'png';
|
|
|
|
req.params.layer = 'all';
|
|
|
|
req.params.format = 'png';
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
step(
|
2015-09-30 01:39:08 +08:00
|
|
|
function reqParams() {
|
2015-09-16 22:18:26 +08:00
|
|
|
self.req2params(req, this);
|
2015-07-10 17:24:32 +08:00
|
|
|
},
|
2015-09-30 01:39:08 +08:00
|
|
|
function getImage(err) {
|
2015-07-10 17:24:32 +08:00
|
|
|
assert.ifError(err);
|
|
|
|
if (center) {
|
2015-07-11 01:10:55 +08:00
|
|
|
self.previewBackend.getImage(
|
|
|
|
new MapStoreMapConfigProvider(self.mapStore, req.context.user, self.userLimitsApi, req.params),
|
2015-07-10 17:24:32 +08:00
|
|
|
format, width, height, zoom, center, this);
|
|
|
|
} else {
|
2015-07-11 01:10:55 +08:00
|
|
|
self.previewBackend.getImage(
|
|
|
|
new MapStoreMapConfigProvider(self.mapStore, req.context.user, self.userLimitsApi, req.params),
|
2015-07-10 17:24:32 +08:00
|
|
|
format, width, height, zoom /* bounds */, this);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
function handleImage(err, image, headers, stats) {
|
|
|
|
req.profiler.done('render-' + format);
|
|
|
|
req.profiler.add(stats || {});
|
|
|
|
|
|
|
|
if (err) {
|
2015-09-17 03:54:56 +08:00
|
|
|
self.sendError(req, res, err, 'STATIC_MAP');
|
2015-07-10 17:24:32 +08:00
|
|
|
} else {
|
2015-09-17 08:05:25 +08:00
|
|
|
res.set('Content-Type', headers['Content-Type'] || 'image/' + format);
|
|
|
|
self.sendResponse(req, res, image, 200);
|
2015-07-14 17:55:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2015-09-17 08:05:25 +08:00
|
|
|
LayergroupController.prototype.sendResponse = function(req, res, body, status, headers) {
|
2015-07-14 17:55:49 +08:00
|
|
|
var self = this;
|
|
|
|
|
2015-09-17 08:03:09 +08:00
|
|
|
res.set('Cache-Control', 'public,max-age=31536000');
|
2015-07-14 17:55:49 +08:00
|
|
|
|
|
|
|
// Set Last-Modified header
|
|
|
|
var lastUpdated;
|
|
|
|
if (req.params.cache_buster) {
|
|
|
|
// Assuming cache_buster is a timestamp
|
|
|
|
lastUpdated = new Date(parseInt(req.params.cache_buster));
|
|
|
|
} else {
|
|
|
|
lastUpdated = new Date();
|
|
|
|
}
|
2015-09-17 08:03:09 +08:00
|
|
|
res.set('Last-Modified', lastUpdated.toUTCString());
|
2015-07-14 17:55:49 +08:00
|
|
|
|
2015-07-14 19:40:41 +08:00
|
|
|
var dbName = req.params.dbname;
|
2015-07-14 17:55:49 +08:00
|
|
|
step(
|
2015-07-14 19:40:41 +08:00
|
|
|
function getAffectedTables() {
|
|
|
|
self.getAffectedTables(req.context.user, dbName, req.params.token, this);
|
2015-07-14 17:55:49 +08:00
|
|
|
},
|
2015-07-14 19:40:41 +08:00
|
|
|
function sendResponse(err, affectedTables) {
|
2015-07-15 02:11:49 +08:00
|
|
|
req.profiler.done('affectedTables');
|
2015-07-14 17:55:49 +08:00
|
|
|
if (err) {
|
2015-09-18 23:23:37 +08:00
|
|
|
global.logger.warn('ERROR generating cache channel: ' + err);
|
2015-07-14 17:55:49 +08:00
|
|
|
}
|
2015-07-14 19:40:41 +08:00
|
|
|
if (!!affectedTables) {
|
2016-02-22 18:40:25 +08:00
|
|
|
res.set('X-Cache-Channel', affectedTables.getCacheChannel());
|
|
|
|
self.surrogateKeysCache.tag(res, affectedTables);
|
2015-07-14 17:55:49 +08:00
|
|
|
}
|
2015-09-17 08:05:25 +08:00
|
|
|
self.send(req, res, body, status, headers);
|
2015-07-14 17:55:49 +08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2015-07-14 19:40:41 +08:00
|
|
|
LayergroupController.prototype.getAffectedTables = function(user, dbName, layergroupId, callback) {
|
2015-07-14 17:55:49 +08:00
|
|
|
|
2015-07-15 02:11:49 +08:00
|
|
|
if (this.layergroupAffectedTables.hasAffectedTables(dbName, layergroupId)) {
|
|
|
|
return callback(null, this.layergroupAffectedTables.get(dbName, layergroupId));
|
|
|
|
}
|
2015-07-14 17:55:49 +08:00
|
|
|
|
2015-07-15 02:11:49 +08:00
|
|
|
var self = this;
|
|
|
|
step(
|
|
|
|
function extractSQL() {
|
2015-07-14 17:55:49 +08:00
|
|
|
step(
|
|
|
|
function loadFromStore() {
|
2015-07-14 19:40:41 +08:00
|
|
|
self.mapStore.load(layergroupId, this);
|
2015-07-14 17:55:49 +08:00
|
|
|
},
|
|
|
|
function getSQL(err, mapConfig) {
|
|
|
|
assert.ifError(err);
|
|
|
|
|
|
|
|
var queries = mapConfig.getLayers()
|
|
|
|
.map(function(lyr) {
|
|
|
|
return lyr.options.sql;
|
|
|
|
})
|
|
|
|
.filter(function(sql) {
|
|
|
|
return !!sql;
|
|
|
|
});
|
|
|
|
|
|
|
|
return queries.length ? queries.join(';') : null;
|
|
|
|
},
|
|
|
|
this
|
|
|
|
);
|
|
|
|
},
|
|
|
|
function findAffectedTables(err, sql) {
|
|
|
|
assert.ifError(err);
|
|
|
|
|
|
|
|
if ( ! sql ) {
|
|
|
|
throw new Error("this request doesn't need an X-Cache-Channel generated");
|
2015-07-10 17:24:32 +08:00
|
|
|
}
|
2015-07-14 17:55:49 +08:00
|
|
|
|
2016-02-22 18:40:25 +08:00
|
|
|
step(
|
|
|
|
function getConnection() {
|
|
|
|
self.pgConnection.getConnection(user, this);
|
|
|
|
},
|
|
|
|
function getAffectedTables(err, connection) {
|
|
|
|
assert.ifError(err);
|
|
|
|
|
|
|
|
QueryTables.getAffectedTablesFromQuery(connection, sql, this);
|
|
|
|
},
|
|
|
|
this
|
|
|
|
);
|
2015-07-14 17:55:49 +08:00
|
|
|
},
|
2016-02-10 02:06:34 +08:00
|
|
|
function buildCacheChannel(err, tables) {
|
2015-07-14 17:55:49 +08:00
|
|
|
assert.ifError(err);
|
2016-02-22 18:40:25 +08:00
|
|
|
self.layergroupAffectedTables.set(dbName, layergroupId, tables);
|
2015-07-14 17:55:49 +08:00
|
|
|
|
2016-02-10 02:06:34 +08:00
|
|
|
return tables;
|
2015-07-14 17:55:49 +08:00
|
|
|
},
|
2016-03-04 02:25:32 +08:00
|
|
|
callback
|
2015-07-10 17:24:32 +08:00
|
|
|
);
|
|
|
|
};
|