Add warnings and notices to JSON response. Closes #104.
This commit is contained in:
parent
493955a468
commit
9389a04030
1
NEWS.md
1
NEWS.md
@ -3,6 +3,7 @@
|
||||
* CartoDB redis interaction delegated to "cartodb-redis" module
|
||||
* Optionally read user-specific database_host and database_password
|
||||
from redis, as per CartoDB-2.5.0 model (#120, #121)
|
||||
* Add warnings and notices to JSON response (#104)
|
||||
|
||||
1.6.3 - 2013-11-10
|
||||
------------------
|
||||
|
@ -82,6 +82,14 @@ p.transform = function(result, options, callback) {
|
||||
total_rows: result.rowCount,
|
||||
rows: result.rows
|
||||
}
|
||||
if ( result.notices ) {
|
||||
for (var i=0; i<result.notices.length; ++i) {
|
||||
var m = result.notices[i];
|
||||
var l = m.severity.toLowerCase() + 's';
|
||||
if ( ! j[l] ) j[l] = [];
|
||||
j[l].push(m.message);
|
||||
}
|
||||
}
|
||||
callback(null, j);
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,14 @@ pg.prototype.handleQueryRow = function(row, result) {
|
||||
result.addRow(row);
|
||||
};
|
||||
|
||||
pg.prototype.handleNotice = function(msg, result) {
|
||||
if ( ! result.notices ) result.notices = [];
|
||||
for (var i=0; i<msg.length; ++i) {
|
||||
var m = msg[i];
|
||||
result.notices.push(m);
|
||||
}
|
||||
};
|
||||
|
||||
pg.prototype.handleQueryEnd = function(result) {
|
||||
if ( this.error ) {
|
||||
this.callback(this.error);
|
||||
@ -104,6 +112,9 @@ pg.prototype.sendResponse = function(opts, callback) {
|
||||
query.on('row', that.handleQueryRow.bind(that));
|
||||
query.on('end', that.handleQueryEnd.bind(that));
|
||||
query.on('error', function(err) { that.error = err; });
|
||||
query.on('notice', function(msg) {
|
||||
that.handleNotice(msg, query._result);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -179,10 +179,20 @@ var PSQL = function(dbopts) {
|
||||
function(err, client, done){
|
||||
if (err) throw err;
|
||||
var query = client.query(sql);
|
||||
|
||||
// forward notices to query
|
||||
var noticeListener = function() {
|
||||
query.emit('notice', arguments);
|
||||
};
|
||||
client.on('notice', noticeListener);
|
||||
|
||||
// NOTE: for some obscure reason passing "done" directly
|
||||
// as the listener works but can be slower
|
||||
// (by x2 factor!)
|
||||
query.on('end', function() { done(); });
|
||||
query.on('end', function() {
|
||||
client.removeListener('notice', noticeListener);
|
||||
done();
|
||||
});
|
||||
return query;
|
||||
},
|
||||
function(err, query){
|
||||
|
@ -63,7 +63,9 @@ The JSON response is as follows:
|
||||
updated_at: "2012-02-12T21:34:08.193Z",
|
||||
valid: true
|
||||
}
|
||||
]
|
||||
],
|
||||
notices: [ 'notice1', 'notice2' ], // optional
|
||||
warnings: [ 'warning1', 'warning2' ] // optional
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1116,6 +1116,115 @@ test('timezone info in JSON output', function(done){
|
||||
);
|
||||
});
|
||||
|
||||
// WARNING and NOTICE in JSON output
|
||||
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/104
|
||||
test('notice and warning info in JSON output', function(done){
|
||||
Step(
|
||||
function addRaiseFunction() {
|
||||
var next = this;
|
||||
assert.response(app, {
|
||||
url: '/api/v1/sql?' + querystring.stringify({
|
||||
q: "create or replace function raise(lvl text, msg text) returns void as $$ begin if lvl = 'notice' then raise notice '%', msg; elsif lvl = 'warning' then raise warning '%', msg; else raise exception '%', msg; end if; end; $$ language plpgsql;",
|
||||
api_key: '1234'
|
||||
}),
|
||||
headers: {host: 'vizzuality.cartodb.com'},
|
||||
method: 'GET'
|
||||
},{ }, function(res) {
|
||||
var err = null;
|
||||
try {
|
||||
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
|
||||
} catch (e) { err = e; }
|
||||
next(err);
|
||||
});
|
||||
},
|
||||
function raiseNotice(err) {
|
||||
if ( err ) throw err;
|
||||
var next = this;
|
||||
assert.response(app, {
|
||||
url: '/api/v1/sql?' + querystring.stringify({
|
||||
q: "select raise('notice', 'hello notice')"
|
||||
}),
|
||||
headers: {host: 'vizzuality.cartodb.com'},
|
||||
method: 'GET'
|
||||
},{}, function(res) {
|
||||
var err = null;
|
||||
try {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('notices'), 'Missing notices from result');
|
||||
assert.equal(parsedBody.notices.length, 1);
|
||||
assert.equal(parsedBody.notices[0], 'hello notice');
|
||||
} catch (e) { err = e; }
|
||||
next(err);
|
||||
});
|
||||
},
|
||||
function raiseWarning(err) {
|
||||
if ( err ) throw err;
|
||||
var next = this;
|
||||
assert.response(app, {
|
||||
url: '/api/v1/sql?' + querystring.stringify({
|
||||
q: "select raise('warning', 'hello warning')"
|
||||
}),
|
||||
headers: {host: 'vizzuality.cartodb.com'},
|
||||
method: 'GET'
|
||||
},{}, function(res) {
|
||||
var err = null;
|
||||
try {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('warnings'), 'Missing warnings from result');
|
||||
assert.equal(parsedBody.warnings.length, 1);
|
||||
assert.equal(parsedBody.warnings[0], 'hello warning');
|
||||
} catch (e) { err = e; }
|
||||
next(err);
|
||||
});
|
||||
},
|
||||
function raiseBothWarningAndNotice(err) {
|
||||
if ( err ) throw err;
|
||||
var next = this;
|
||||
assert.response(app, {
|
||||
url: '/api/v1/sql?' + querystring.stringify({
|
||||
q: "select raise('warning', 'hello again warning'), raise('notice', 'hello again notice');"
|
||||
}),
|
||||
headers: {host: 'vizzuality.cartodb.com'},
|
||||
method: 'GET'
|
||||
},{}, function(res) {
|
||||
var err = null;
|
||||
try {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
assert.ok(parsedBody.hasOwnProperty('warnings'), 'Missing warnings from result');
|
||||
assert.equal(parsedBody.warnings.length, 1);
|
||||
assert.equal(parsedBody.warnings[0], 'hello again warning');
|
||||
assert.ok(parsedBody.hasOwnProperty('notices'), 'Missing notices from result');
|
||||
assert.equal(parsedBody.notices.length, 1);
|
||||
assert.equal(parsedBody.notices[0], 'hello again notice');
|
||||
} catch (e) { err = e; }
|
||||
next(err);
|
||||
});
|
||||
},
|
||||
function delRaiseFunction(err) {
|
||||
var next = this;
|
||||
assert.response(app, {
|
||||
url: '/api/v1/sql?' + querystring.stringify({
|
||||
q: "DROP function raise(text, text)",
|
||||
api_key: '1234'
|
||||
}),
|
||||
headers: {host: 'vizzuality.cartodb.com'},
|
||||
method: 'GET'
|
||||
},{ }, function(res) {
|
||||
try {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
} catch (e) { err = new Error(err + ',' + e); }
|
||||
next(err);
|
||||
});
|
||||
},
|
||||
function finish(err) {
|
||||
done(err);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* CORS
|
||||
|
Loading…
Reference in New Issue
Block a user