diff --git a/lib/cartodb/api/query_tables_api.js b/lib/cartodb/api/query_tables_api.js index 63b87158..fc0e2932 100644 --- a/lib/cartodb/api/query_tables_api.js +++ b/lib/cartodb/api/query_tables_api.js @@ -1,9 +1,5 @@ -var PSQL = require('cartodb-psql'); -var step = require('step'); - -function QueryTablesApi(pgConnection, metadataBackend) { - this.pgConnection = pgConnection; - this.metadataBackend = metadataBackend; +function QueryTablesApi(pgQueryRunner) { + this.pgQueryRunner = pgQueryRunner; } var affectedTableRegexCache = { @@ -20,7 +16,7 @@ QueryTablesApi.prototype.getAffectedTablesInQuery = function (username, sql, cal var query = 'SELECT CDB_QueryTables($windshaft$' + prepareSql(sql) + '$windshaft$)'; - this.runQuery(username, query, handleAffectedTablesInQueryRows, callback); + this.pgQueryRunner.run(username, query, handleAffectedTablesInQueryRows, callback); }; function handleAffectedTablesInQueryRows(err, rows, callback) { @@ -46,7 +42,7 @@ QueryTablesApi.prototype.getAffectedTablesAndLastUpdatedTime = function (usernam 'WHERE m.tabname = any ((SELECT tablenames from querytables)::regclass[])' ].join(' '); - this.runQuery(username, query, handleAffectedTablesAndLastUpdatedTimeRows, callback); + this.pgQueryRunner.run(username, query, handleAffectedTablesAndLastUpdatedTimeRows, callback); }; function handleAffectedTablesAndLastUpdatedTimeRows(err, rows, callback) { @@ -69,43 +65,6 @@ function handleAffectedTablesAndLastUpdatedTimeRows(err, rows, callback) { }); } - -QueryTablesApi.prototype.runQuery = function(username, query, queryHandler, callback) { - var self = this; - - var params = {}; - - step( - function setAuth() { - self.pgConnection.setDBAuth(username, params, this); - }, - function setConn(err) { - if (err) { - throw err; - } - self.pgConnection.setDBConn(username, params, this); - }, - function executeQuery(err) { - if (err) { - throw err; - } - var psql = new PSQL({ - user: params.dbuser, - pass: params.dbpass, - host: params.dbhost, - port: params.dbport, - dbname: params.dbname - }); - psql.query(query, function(err, resultSet) { - resultSet = resultSet || {}; - var rows = resultSet.rows || []; - queryHandler(err, rows, callback); - }); - } - ); -}; - - function prepareSql(sql) { return sql .replace(affectedTableRegexCache.bbox, 'ST_MakeEnvelope(0,0,0,0)') diff --git a/lib/cartodb/backends/pg_query_runner.js b/lib/cartodb/backends/pg_query_runner.js new file mode 100644 index 00000000..ed6c88db --- /dev/null +++ b/lib/cartodb/backends/pg_query_runner.js @@ -0,0 +1,44 @@ +var PSQL = require('cartodb-psql'); +var step = require('step'); + +function PgQueryRunner(pgConnection) { + this.pgConnection = pgConnection; +} + +module.exports = PgQueryRunner; + + +PgQueryRunner.prototype.run = function(username, query, queryHandler, callback) { + var self = this; + + var params = {}; + + step( + function setAuth() { + self.pgConnection.setDBAuth(username, params, this); + }, + function setConn(err) { + if (err) { + throw err; + } + self.pgConnection.setDBConn(username, params, this); + }, + function executeQuery(err) { + if (err) { + throw err; + } + var psql = new PSQL({ + user: params.dbuser, + pass: params.dbpass, + host: params.dbhost, + port: params.dbport, + dbname: params.dbname + }); + psql.query(query, function(err, resultSet) { + resultSet = resultSet || {}; + var rows = resultSet.rows || []; + queryHandler(err, rows, callback); + }); + } + ); +}; diff --git a/lib/cartodb/server_options.js b/lib/cartodb/server_options.js index a3f9d029..65c94808 100644 --- a/lib/cartodb/server_options.js +++ b/lib/cartodb/server_options.js @@ -5,6 +5,7 @@ var assert = require('assert'); var RedisPool = require('redis-mpool'); var QueryTablesApi = require('./api/query_tables_api'); +var PgQueryRunner = require('./backends/pg_query_runner'); var PgConnection = require('./backends/pg_connection'); var TemplateMaps = require('./template_maps.js'); var MapConfigNamedLayersAdapter = require('./models/mapconfig_named_layers_adapter'); @@ -25,11 +26,12 @@ var REQUEST_QUERY_PARAMS_WHITELIST = [ module.exports = function(redisPool) { redisPool = redisPool || new RedisPool(_.extend(global.environment.redis, {name: 'windshaft:server_options'})); - var cartoData = require('cartodb-redis')({ pool: redisPool }), - lzmaWorker = new LZMA(), - pgConnection = new PgConnection(cartoData), - queryTablesApi = new QueryTablesApi(pgConnection, cartoData), - cdbRequest = new CdbRequest(); + var cartoData = require('cartodb-redis')({ pool: redisPool }); + var lzmaWorker = new LZMA(); + var pgConnection = new PgConnection(cartoData); + var pgQueryRunner = new PgQueryRunner(pgConnection); + var queryTablesApi = new QueryTablesApi(pgQueryRunner); + var cdbRequest = new CdbRequest(); var rendererConfig = _.defaults(global.environment.renderer || {}, { cache_ttl: 60000, // milliseconds diff --git a/test/acceptance/multilayer_server.js b/test/acceptance/multilayer_server.js index 79b59a3c..e2427543 100644 --- a/test/acceptance/multilayer_server.js +++ b/test/acceptance/multilayer_server.js @@ -6,7 +6,7 @@ var redis = require('redis'); var _ = require('underscore'); -var QueryTablesApi = require('../../lib/cartodb/api/query_tables_api'); +var PgQueryRunner = require('../../lib/cartodb/backends/pg_query_runner'); var CartodbWindshaft = require('../../lib/cartodb/cartodb_windshaft'); var serverOptions = require('../../lib/cartodb/server_options')(); var server = new CartodbWindshaft(serverOptions); @@ -253,8 +253,8 @@ describe('tests from old api translated to multilayer', function() { it("creates layergroup fails when postgresql queries fail to figure affected tables in query", function(done) { - var runQueryFn = QueryTablesApi.prototype.runQuery; - QueryTablesApi.prototype.runQuery = function(username, query, queryHandler, callback) { + var runQueryFn = PgQueryRunner.prototype.run; + PgQueryRunner.prototype.run = function(username, query, queryHandler, callback) { return queryHandler(new Error('fake error message'), [], callback); }; @@ -272,7 +272,7 @@ describe('tests from old api translated to multilayer', function() { status: 400 }, function(res) { - QueryTablesApi.prototype.runQuery = runQueryFn; + PgQueryRunner.prototype.run = runQueryFn; assert.ok(!res.headers.hasOwnProperty('x-cache-channel')); @@ -300,8 +300,8 @@ describe('tests from old api translated to multilayer', function() { status: 200 }, function(res) { - var runQueryFn = QueryTablesApi.prototype.runQuery; - QueryTablesApi.prototype.runQuery = function(username, query, queryHandler, callback) { + var runQueryFn = PgQueryRunner.prototype.run; + PgQueryRunner.prototype.run = function(username, query, queryHandler, callback) { return queryHandler(new Error('failed to query database for affected tables'), [], callback); }; @@ -327,7 +327,7 @@ describe('tests from old api translated to multilayer', function() { }, function(res) { assert.ok(!res.headers.hasOwnProperty('x-cache-channel')); - QueryTablesApi.prototype.runQuery = runQueryFn; + PgQueryRunner.prototype.run = runQueryFn; done(); } );