diff --git a/lib/cartodb/backends/dataview.js b/lib/cartodb/backends/dataview.js index ef11fc34..67500519 100644 --- a/lib/cartodb/backends/dataview.js +++ b/lib/cartodb/backends/dataview.js @@ -27,7 +27,7 @@ DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, param function getMapConfig() { mapConfigProvider.getMapConfig(this); }, - function getWidget(err, _mapConfig) { + function _getDataviewDefinition(err, _mapConfig) { assert.ifError(err); mapConfig = _mapConfig; @@ -131,6 +131,115 @@ DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, param ); }; +DataviewBackend.prototype.search = function (mapConfigProvider, user, params, callback) { + var timer = new Timer(); + + var dataviewName = params.dataviewName; + + var mapConfig; + var dataviewDefinition; + step( + function getMapConfig() { + mapConfigProvider.getMapConfig(this); + }, + function _getDataviewDefinition(err, _mapConfig) { + assert.ifError(err); + + mapConfig = _mapConfig; + + var _dataviewDefinition = getDataviewDefinition(mapConfig.obj(), dataviewName); + if (!_dataviewDefinition) { + throw new Error("Dataview '" + dataviewName + "' does not exists"); + } + + dataviewDefinition = _dataviewDefinition; + + return dataviewDefinition; + }, + function loadAnalysis(err) { + assert.ifError(err); + + var analysisConfiguration = { + db: { + host: params.dbhost, + port: params.dbport, + dbname: params.dbname, + user: params.dbuser, + pass: params.dbpassword + }, + batch: { + // TODO load this from configuration + endpoint: 'http://127.0.0.1:8080/api/v1/sql/job', + username: user, + apiKey: params.api_key + } + }; + + var sourceId = dataviewDefinition.source.id; + var analysisDefinition = getAnalysisDefinition(mapConfig.obj().analyses, sourceId); + + var next = this; + + camshaft.create(analysisConfiguration, analysisDefinition, function(err, analysis) { + if (err) { + return next(err); + } + + var sourceId2Node = {}; + var rootNode = analysis.getRoot(); + if (rootNode.params && rootNode.params.id) { + sourceId2Node[rootNode.params.id] = rootNode; + } + + analysis.getSortedNodes().forEach(function(node) { + if (node.params && node.params.id) { + sourceId2Node[node.params.id] = node; + } + }); + + var node = sourceId2Node[sourceId]; + + if (!node) { + return next(new Error('Analysis node not found for dataview')); + } + + return next(null, node); + }); + }, + function runDataviewQuery(err, node) { + assert.ifError(err); + + var pg = new PSQL(dbParamsFromReqParams(params)); + + var ownFilter = +params.own_filter; + ownFilter = !!ownFilter; + + var query; + if (ownFilter) { + query = node.getQuery(); + } else { + var applyFilters = {}; + applyFilters[dataviewName] = false; + query = node.getQuery(applyFilters); + } + + if (params.bbox) { + var bboxFilter = new BBoxFilter({column: 'the_geom', srid: 4326}, {bbox: params.bbox}); + query = bboxFilter.sql(query); + } + + var userQuery = params.q; + console.log(userQuery); + + var dataview = DataviewFactory.getDataview(query, dataviewDefinition); + dataview.search(pg, userQuery, this); + }, + function returnCallback(err, result) { + return callback(err, result, timer.getTimes()); + } + ); +}; + function getAnalysisDefinition(mapConfigAnalyses, sourceId) { mapConfigAnalyses = mapConfigAnalyses || []; for (var i = 0; i < mapConfigAnalyses.length; i++) { diff --git a/lib/cartodb/controllers/layergroup.js b/lib/cartodb/controllers/layergroup.js index fbf8da92..b469a096 100644 --- a/lib/cartodb/controllers/layergroup.js +++ b/lib/cartodb/controllers/layergroup.js @@ -86,6 +86,10 @@ LayergroupController.prototype.register = function(app) { app.get(app.base_url_mapconfig + '/:token/dataview/:dataviewName', cors(), userMiddleware, this.dataview.bind(this)); + + app.get(app.base_url_mapconfig + + '/:token/dataview/:dataviewName/search', cors(), userMiddleware, + this.dataviewSearch.bind(this)); }; LayergroupController.prototype.dataview = function(req, res) { @@ -95,7 +99,7 @@ LayergroupController.prototype.dataview = function(req, res) { function setupParams() { self.req2params(req, this); }, - function retrieveList(err) { + function retrieveDataview(err) { assert.ifError(err); var mapConfigProvider = new MapStoreMapConfigProvider( @@ -107,7 +111,35 @@ LayergroupController.prototype.dataview = function(req, res) { req.profiler.add(stats || {}); if (err) { - self.sendError(req, res, err, 'GET WIDGET'); + self.sendError(req, res, err, 'GET DATAVIEW'); + } else { + self.sendResponse(req, res, tile, 200); + } + } + ); + +}; + +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); + }, + function finish(err, tile, stats) { + req.profiler.add(stats || {}); + + if (err) { + self.sendError(req, res, err, 'GET DATAVIEW SEARCH'); } else { self.sendResponse(req, res, tile, 200); }