This is an automated email from the ASF dual-hosted git repository. jorgebg pushed a commit to branch TINKERPOP-2064 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 2bf0845de8b63329ce781ae3662505cc2cb156e5 Author: Jorge Bay Gondra <jorgebaygon...@gmail.com> AuthorDate: Mon Nov 5 14:36:29 2018 +0100 TINKERPOP-2064: Expose Response attributes in JavaScript Driver --- CHANGELOG.asciidoc | 2 +- .../gremlin-javascript/lib/driver/connection.js | 4 ++-- .../gremlin-javascript/lib/driver/result-set.js | 11 ++++++++++- .../main/javascript/gremlin-javascript/lib/utils.js | 20 +++++++++++++++++++- .../test/integration/client-tests.js | 8 ++++++++ .../gremlin-javascript/test/unit/result-set-test.js | 19 ++++++++++++++----- 6 files changed, 54 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 402ed7c..6821906 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -44,7 +44,7 @@ This release also includes changes from <<release-3-3-3, 3.3.3>>. * Bumped to Spark 2.3.1. * Bumped to Groovy 2.5.2. * Modified Gremlin Server to return a "host" status attribute on responses. -* Added ability to the Java, .NET and Python drivers to retrieve status attributes returned from the server. +* Added ability to the Java, .NET, Python and JavaScript drivers to retrieve status attributes returned from the server. * Modified Java and Gremlin.Net `ResponseException` to include status code and status attributes. * Modified Python `GremlinServerError` to include status attributes. * Modified the return type for `IGremlinClient.SubmitAsync()` to be a `ResultSet` rather than an `IReadOnlyCollection`. diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index cc03449..238bc2c 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -193,7 +193,7 @@ class Connection { switch (response.status.code) { case responseStatusCode.noContent: this._clearHandler(response.requestId); - return handler.callback(null, new ResultSet(utils.emptyArray)); + return handler.callback(null, new ResultSet(utils.emptyArray, response.status.attributes)); case responseStatusCode.partialContent: handler.result = handler.result || []; handler.result.push.apply(handler.result, response.result.data); @@ -206,7 +206,7 @@ class Connection { handler.result = response.result.data; } this._clearHandler(response.requestId); - return handler.callback(null, new ResultSet(handler.result)); + return handler.callback(null, new ResultSet(handler.result, response.status.attributes)); } } diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/result-set.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/result-set.js index 1860aea..c4dee05 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/result-set.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/result-set.js @@ -24,6 +24,8 @@ const util = require('util'); const inspect = util.inspect.custom || 'inspect'; +const utils = require('../utils'); +const emptyMap = Object.freeze(new utils.ImmutableMap()); /** * Represents the response returned from the execution of a Gremlin traversal or script. @@ -33,8 +35,9 @@ class ResultSet { /** * Creates a new instance of {@link ResultSet}. * @param {Array} items + * @param {Map} [attributes] */ - constructor(items) { + constructor(items, attributes) { if (!Array.isArray(items)) { throw new TypeError('items must be an Array instance'); } @@ -42,6 +45,12 @@ class ResultSet { this._items = items; /** + * Gets a Map representing the attributes of the response. + * @type {Map} + */ + this.attributes = attributes || emptyMap; + + /** * Gets the amount of items in the result. * @type {Number} */ diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js index c6b091f..f996dba 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js @@ -55,4 +55,22 @@ exports.getUuid = function getUuid() { hex.substr(20, 12)); }; -exports.emptyArray = Object.freeze([]); \ No newline at end of file +exports.emptyArray = Object.freeze([]); + +class ImmutableMap extends Map { + constructor(iterable) { + super(iterable); + } + + set(){ + return this; + } + + ['delete'](){ + return false; + } + + clear() { } +} + +exports.ImmutableMap = ImmutableMap; diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-tests.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-tests.js index 92e709c..56c7c58 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-tests.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-tests.js @@ -66,5 +66,13 @@ describe('Client', function () { assert.strictEqual(result.first(), 'Cardinality:set'); }); }); + + it('should retrieve the attributes', () => { + return client.submit(new Bytecode().addStep('V', []).addStep('tail', [])) + .then(rs => { + assert.ok(rs.attributes instanceof Map); + assert.ok(rs.attributes.get('host')); + }); + }); }); }); \ No newline at end of file diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/result-set-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/result-set-test.js index 9eb99af..d50c3a1 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/result-set-test.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/result-set-test.js @@ -76,11 +76,20 @@ describe('ResultSet', function () { }); }); - describe('#traversers', () => { - it('should expose deprecated property', () => { - const items = [ 'a', 'b' ]; - // Traversers property is going to be removed in upcoming versions - assert.strictEqual(new ResultSet(items).traversers, items); + //TODO: Document traversers property removed. + //TODO: Rebase master + describe('#attributes', () => { + it('should default to an empty Map when not defined', () => { + const rs = new ResultSet([]); + assert.ok(rs.attributes instanceof Map); + assert.strictEqual(rs.attributes.size, 0); + }); + + it('should return the attributes when defined', () => { + const attributes = new Map([['a', 1], ['b', 1]]); + const rs = new ResultSet([], attributes); + assert.ok(rs.attributes instanceof Map); + assert.strictEqual(rs.attributes, attributes); }); }); }); \ No newline at end of file