Improve PgQueryRunner public run method

Last param is callback function, receiving err + result, no need to
keep passing two functions, the query handler and the final callback.

It should be easier to understand now as query handler was in a position
where it had to know about receiving a callback, that was exposing an
implementation detail of PgQueryRunner.
This commit is contained in:
Raul Ochoa
2015-12-30 17:44:49 +01:00
parent 69fdaca41f
commit 76cbc2f863
4 changed files with 65 additions and 70 deletions

View File

@@ -13,26 +13,22 @@ module.exports = QueryTablesApi;
QueryTablesApi.prototype.getAffectedTablesInQuery = function (username, sql, callback) {
var query = 'SELECT CDB_QueryTablesText($windshaft$' + prepareSql(sql) + '$windshaft$)';
this.pgQueryRunner.run(username, query, handleAffectedTablesInQueryRows, callback);
this.pgQueryRunner.run(username, query, function handleAffectedTablesInQueryRows (err, rows) {
if (err){
var msg = err.message ? err.message : err;
callback(new Error('could not fetch source tables: ' + msg));
return;
}
// This is an Array, so no need to split into parts
var tableNames = rows[0].cdb_querytablestext;
return callback(null, tableNames);
});
};
function handleAffectedTablesInQueryRows(err, rows, callback) {
if (err){
var msg = err.message ? err.message : err;
callback(new Error('could not fetch source tables: ' + msg));
return;
}
// This is an Array, so no need to split into parts
var tableNames = rows[0].cdb_querytablestext;
callback(null, tableNames);
}
QueryTablesApi.prototype.getAffectedTablesAndLastUpdatedTime = function (username, sql, callback) {
var query = [
'WITH querytables AS (',
'SELECT * FROM CDB_QueryTablesText($windshaft$' + prepareSql(sql) + '$windshaft$) as tablenames',
@@ -42,28 +38,26 @@ QueryTablesApi.prototype.getAffectedTablesAndLastUpdatedTime = function (usernam
'WHERE m.tabname = any ((SELECT tablenames from querytables)::regclass[])'
].join(' ');
this.pgQueryRunner.run(username, query, handleAffectedTablesAndLastUpdatedTimeRows, callback);
};
this.pgQueryRunner.run(username, query, function handleAffectedTablesAndLastUpdatedTimeRows (err, rows) {
if (err || rows.length === 0) {
var msg = err.message ? err.message : err;
callback(new Error('could not fetch affected tables or last updated time: ' + msg));
return;
}
function handleAffectedTablesAndLastUpdatedTimeRows(err, rows, callback) {
if (err || rows.length === 0) {
var msg = err.message ? err.message : err;
callback(new Error('could not fetch affected tables or last updated time: ' + msg));
return;
}
var result = rows[0];
var result = rows[0];
// This is an Array, so no need to split into parts
var tableNames = result.tablenames;
// This is an Array, so no need to split into parts
var tableNames = result.tablenames;
var lastUpdatedTime = result.max || 0;
var lastUpdatedTime = result.max || 0;
callback(null, {
affectedTables: tableNames,
lastUpdatedTime: lastUpdatedTime * 1000
callback(null, {
affectedTables: tableNames,
lastUpdatedTime: lastUpdatedTime * 1000
});
});
}
};
QueryTablesApi.prototype.getLastUpdatedTime = function (username, tableNames, callback) {
if (!Array.isArray(tableNames) || tableNames.length === 0) {
@@ -77,23 +71,21 @@ QueryTablesApi.prototype.getLastUpdatedTime = function (username, tableNames, ca
'])'
].join(' ');
this.pgQueryRunner.run(username, query, handleLastUpdatedTimeRows, callback);
this.pgQueryRunner.run(username, query, function handleLastUpdatedTimeRows (err, rows) {
if (err) {
var msg = err.message ? err.message : err;
return callback(new Error('could not fetch affected tables or last updated time: ' + msg));
}
// when the table has not updated_at means it hasn't been changed so a default last_updated is set
var lastUpdated = 0;
if (rows.length !== 0) {
lastUpdated = rows[0].max || 0;
}
return callback(null, lastUpdated*1000);
});
};
function handleLastUpdatedTimeRows(err, rows, callback) {
if (err) {
var msg = err.message ? err.message : err;
return callback(new Error('could not fetch affected tables or last updated time: ' + msg));
}
// when the table has not updated_at means it hasn't been changed so a default last_updated is set
var lastUpdated = 0;
if (rows.length !== 0) {
lastUpdated = rows[0].max || 0;
}
return callback(null, lastUpdated*1000);
}
function prepareSql(sql) {
return sql
.replace(affectedTableRegexCache.bbox, 'ST_MakeEnvelope(0,0,0,0)')

View File

@@ -35,19 +35,17 @@ TablesExtentApi.prototype.getBounds = function (username, tableNames, callback)
"FROM ext"
].join(' ');
this.pgQueryRunner.run(username, query, handleBoundsResult, callback);
this.pgQueryRunner.run(username, query, function handleBoundsResult (err, rows) {
if (err) {
var msg = err.message ? err.message : err;
return callback(new Error('could not fetch source tables: ' + msg));
}
var result = null;
if (rows.length > 0) {
result = {
bounds: rows[0]
};
}
callback(null, result);
});
};
function handleBoundsResult(err, rows, callback) {
if (err) {
var msg = err.message ? err.message : err;
return callback(new Error('could not fetch source tables: ' + msg));
}
var result = null;
if (rows.length > 0) {
result = {
bounds: rows[0]
};
}
callback(null, result);
}

View File

@@ -8,8 +8,14 @@ function PgQueryRunner(pgConnection) {
module.exports = PgQueryRunner;
PgQueryRunner.prototype.run = function(username, query, queryHandler, callback) {
/**
* Runs `query` with `username`'s PostgreSQL role, callback receives error and rows array.
*
* @param {String} username
* @param {String} query
* @param {Function} callback function({Error}, {Array}) second argument is guaranteed to be an array
*/
PgQueryRunner.prototype.run = function(username, query, callback) {
var self = this;
var params = {};
@@ -33,8 +39,7 @@ PgQueryRunner.prototype.run = function(username, query, queryHandler, callback)
});
psql.query(query, function(err, resultSet) {
resultSet = resultSet || {};
var rows = resultSet.rows || [];
queryHandler(err, rows, callback);
return callback(err, resultSet.rows || []);
});
}
);

View File

@@ -310,8 +310,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 = PgQueryRunner.prototype.run;
PgQueryRunner.prototype.run = function(username, query, queryHandler, callback) {
return queryHandler(new Error('fake error message'), [], callback);
PgQueryRunner.prototype.run = function(username, query, callback) {
return callback(new Error('fake error message'), []);
};
var layergroup = singleLayergroupConfig('select * from gadm4', '#gadm4 { marker-fill: red; }');
@@ -365,8 +365,8 @@ describe('tests from old api translated to multilayer', function() {
keysToDelete['user:localhost:mapviews:global'] = 5;
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);
PgQueryRunner.prototype.run = function(username, query, callback) {
return callback(new Error('failed to query database for affected tables'), []);
};
// reset internal cacheChannel cache