diff --git a/src/client.js b/src/client.js index 3028bd7c2..0bd0becbb 100644 --- a/src/client.js +++ b/src/client.js @@ -163,6 +163,13 @@ assign(Client.prototype, { return sql; }, + postProcessResponse(resp) { + if (this.config.postProcessResponse) { + return this.config.postProcessResponse(resp); + } + return resp; + }, + wrapIdentifier(value) { if (this.config.wrapIdentifier) { return this.config.wrapIdentifier(value, this.wrapIdentifierImpl); diff --git a/src/runner.js b/src/runner.js index f87b2018b..ec08a7475 100644 --- a/src/runner.js +++ b/src/runner.js @@ -132,19 +132,24 @@ assign(Runner.prototype, { return queryPromise .then((resp) => { const processedResponse = this.client.processResponse(resp, runner); + const postProcessedResponse = this.client + .postProcessResponse(processedResponse); + this.builder.emit( 'query-response', - processedResponse, + postProcessedResponse, assign({__knexUid: this.connection.__knexUid}, obj), this.builder ); + this.client.emit( 'query-response', - processedResponse, + postProcessedResponse, assign({__knexUid: this.connection.__knexUid}, obj), this.builder ); - return processedResponse; + + return postProcessedResponse; }).catch(Promise.TimeoutError, error => { const { timeout, sql, bindings } = obj; diff --git a/test/integration/builder/additional.js b/test/integration/builder/additional.js index 68b0b6d3a..25771254b 100644 --- a/test/integration/builder/additional.js +++ b/test/integration/builder/additional.js @@ -10,6 +10,42 @@ module.exports = function(knex) { describe('Additional', function () { + describe("Custom response processing", () => { + + before('setup custom response handler', () => { + knex.client.config.postProcessResponse = (response) => { + response.callCount = response.callCount ? (response.callCount + 1) : 1; + return response; + }; + }); + + after('restore client configuration', () => { + knex.client.config.postProcessResponse = null; + }); + + it('should process normal response', () => { + return knex('accounts').limit(1).then(res => { + expect(res.callCount).to.equal(1); + }); + }); + + it('should process raw response', () => { + return knex.raw('select * from ??', ['accounts']).then(res => { + }); + }); + + it('should process response done in transaction', () => { + return knex.transaction(trx => { + return trx('accounts').limit(1).then(res => { + expect(res.callCount).to.equal(1); + return res; + }); + }).then(res => { + expect(res.callCount).to.equal(1); + }); + }); + }); + it('should forward the .get() function from bluebird', function() { return knex('accounts').select().limit(1).then(function(accounts){ var firstAccount = accounts[0]; @@ -401,10 +437,10 @@ module.exports = function(knex) { // Ensure sleep command is removed. // This query will hang if a connection gets released back to the pool - // too early. + // too early. // 50ms delay since killing query doesn't seem to have immediate effect to the process listing return Promise.resolve().then().delay(50) - .then(function () { + .then(function () { return knex.raw('SHOW PROCESSLIST'); }) .then(function(results) { @@ -464,6 +500,7 @@ module.exports = function(knex) { }) }) .then(function() { + knex.removeListener('query-response', onQueryResponse); expect(queryCount).to.equal(4); }) }); @@ -487,6 +524,7 @@ module.exports = function(knex) { expect(true).to.equal(false); //Should not be resolved }) .catch(function() { + knex.removeListener('query-error', onQueryError); expect(queryCount).to.equal(2); }) });