You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2018/10/08 19:02:04 UTC

[tinkerpop] branch TINKERPOP-1959-tp33 updated (6c7a8cd -> 94f7477)

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a change to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git.


 discard 6c7a8cd  Merge branch 'TINKERPOP-1959' into TINKERPOP-1959-tp33
 discard 93bb752  f
    omit 6132b7a  TINKERPOP-1959 Minor fix to upgrade docs
    omit 54a12eb  TINKERPOP-1959 Minor fixes to upgrade docs
    omit 67e56dd  TINKERPOP-1959 Refactored request arg serialization to be more general
    omit ad624be  TINKERPOP-1959 Handled EnumValue serialization in script bindings
    omit d43031a  Merge branch 'pr-922' into TINKERPOP-1959
    omit cbedb32  Test added to Client to confirm correct handling of non JS native types. Changed script submission to accept GraphSON v2. Reverted TraversalSource template to original. Removed configuration of standardOp Processor. Updated CHANGELOG and upgrade documentation.
    omit 12e8350  Changed Client implementation to wrap DriverRemoteConnection
    omit e464d82  Fix for numbers not being translated correctly in the bytecode translator
    omit a8e5454  Client and Translator classes for better handling of scripts
    omit 3f87545  Fixed issue where eval was added to wrong class in GraphTravesal
    omit 090f139  Fix on eval() incorrect documentation
    omit c04ddae  Refactor of RemoteStrategy apply()
    omit b6478d6  Initial Commit for TINKERPOP-1959 solution.
     add 88b5347  CTR: added missing import
     new ef34c12  Initial Commit for TINKERPOP-1959 solution.
     new 4b5d25a  Refactor of RemoteStrategy apply()
     new b6c8c00  Fix on eval() incorrect documentation
     new 9f4cfc7  Fixed issue where eval was added to wrong class in GraphTravesal
     new a72c6fb  Client and Translator classes for better handling of scripts
     new a59780f  Fix for numbers not being translated correctly in the bytecode translator
     new 20b7687  Changed Client implementation to wrap DriverRemoteConnection
     new d12f117  Test added to Client to confirm correct handling of non JS native types. Changed script submission to accept GraphSON v2. Reverted TraversalSource template to original. Removed configuration of standardOp Processor. Updated CHANGELOG and upgrade documentation.
     new 22c8821  TINKERPOP-1959 Handled EnumValue serialization in script bindings
     new cfa6c04  TINKERPOP-1959 Refactored request arg serialization to be more general
     new 0fb7c9e  TINKERPOP-1959 Minor fixes to upgrade docs
     new 94f7477  TINKERPOP-1959 Minor fix to upgrade docs

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (6c7a8cd)
            \
             N -- N -- N   refs/heads/TINKERPOP-1959-tp33 (94f7477)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 12 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:


[tinkerpop] 03/12: Fix on eval() incorrect documentation

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit b6c8c0022439376b0df80c543beee1c832a78033
Author: Matthew Allen <ma...@runbox.com>
AuthorDate: Sat Aug 25 00:02:27 2018 +0100

    Fix on eval() incorrect documentation
---
 gremlin-javascript/glv/GraphTraversalSource.template | 3 +--
 gremlin-javascript/glv/TraversalSource.template      | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/gremlin-javascript/glv/GraphTraversalSource.template b/gremlin-javascript/glv/GraphTraversalSource.template
index 3f8e715..e48dd67 100644
--- a/gremlin-javascript/glv/GraphTraversalSource.template
+++ b/gremlin-javascript/glv/GraphTraversalSource.template
@@ -109,9 +109,8 @@ class GraphTraversal extends Traversal {
   /**
    * Send a Gremlin-Groovy script to the server. If a script is not passed in 
    * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} gremlinScript The script to send to server
+   * @param {string} script The script to send to server
    * @param {array} bindings Map of bindings
-   * @param {*} options Options to configure the script sending
    */
   eval(script, bindings) {
     this.bytecode.addStep('eval', [ script, bindings ]);
diff --git a/gremlin-javascript/glv/TraversalSource.template b/gremlin-javascript/glv/TraversalSource.template
index 6afe868..9824273 100644
--- a/gremlin-javascript/glv/TraversalSource.template
+++ b/gremlin-javascript/glv/TraversalSource.template
@@ -81,9 +81,8 @@ class Traversal {
   /**
    * Send a Gremlin-Groovy script to the server. If a script is not passed in 
    * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} gremlinScript The script to send to server
+   * @param {string} script The script to send to server
    * @param {array} bindings Map of bindings
-   * @param {*} options Options to configure the script sending
    */
   eval(script, bindings) {
     this.bytecode.addStep('eval', [ script, bindings ]);


[tinkerpop] 12/12: TINKERPOP-1959 Minor fix to upgrade docs

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 94f74777abf1b46709eeb662c88d04403963f9fd
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Mon Oct 8 11:12:43 2018 -0400

    TINKERPOP-1959 Minor fix to upgrade docs
---
 docs/src/upgrade/release-3.2.x-incubating.asciidoc | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index 72c0a1c..12f95af 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -137,8 +137,7 @@ const connection = new gremlin.driver.Client('ws://localhost:8182/gremlin', { tr
 const translator = new gremlin.process.Translator('g');
 
 const g = graph.traversal();
-g.V().tail();
-const script = translator.translate(g.getBytecode());
+const script = translator.translate(g.V().tail().getBytecode());
 
 connection.submit(script)
     .then(response => {


[tinkerpop] 09/12: TINKERPOP-1959 Handled EnumValue serialization in script bindings

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 22c8821c601dfb3fc18de028cc3612085e421c17
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Fri Oct 5 08:36:25 2018 -0400

    TINKERPOP-1959 Handled EnumValue serialization in script bindings
---
 .../gremlin-javascript/lib/driver/driver-remote-connection.js  |  7 ++++++-
 .../gremlin-javascript/test/integration/client-tests.js        | 10 ++--------
 .../javascript/gremlin-javascript/test/unit/graphson-test.js   |  4 ++++
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
index d8bb8dc..5b84b04 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
@@ -24,6 +24,7 @@
 
 const WebSocket = require('ws');
 const util = require('util');
+const t = require('../process/traversal');
 const RemoteConnection = require('./remote-connection').RemoteConnection;
 const utils = require('../utils');
 const serializer = require('../structure/io/graph-serializer');
@@ -218,6 +219,10 @@ class DriverRemoteConnection extends RemoteConnection {
       return args.map(val => this._adaptArgs(val));
     }
 
+    if (args instanceof t.EnumValue) {
+       return this._writer.adaptObject(args);
+    }
+
     if (args instanceof Object) {
       let newObj = {};
       Object.keys(args).forEach((key) => {
@@ -225,7 +230,7 @@ class DriverRemoteConnection extends RemoteConnection {
       });
       return newObj;
     }
-    
+
     return this._writer.adaptObject(args);
   }
 
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 6fcb892..88d871a 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
@@ -63,16 +63,10 @@ describe('Client', function () {
         });
     });
     it('should send and parse a script with non-native javascript bindings', function () {
-      /*return connection.submit('card.toString()', { card: t.cardinality.set })
+      return connection.submit('card.class.simpleName + ":" + card', { card: t.cardinality.set } )
         .then(function (response) {
-          console.log(response);
           assert.ok(response);
-          assert.ok(response.traversers);
-        });*/
-      return connection.submit('g.addV().property(card, nm, val)', { card: t.cardinality.set, nm: 'test', val: 12 } )
-        .then(function (response) {
-          assert.ok(response);
-          assert.ok(response.traversers);
+          assert.strictEqual(response.traversers[0], 'Cardinality:set');
         });
     });
   });
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphson-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphson-test.js
index 66a36c6..b23e542 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphson-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphson-test.js
@@ -151,6 +151,10 @@ describe('GraphSONWriter', function () {
     assert.strictEqual(writer.write(true), 'true');
     assert.strictEqual(writer.write(false), 'false');
   });
+  it('should write enum values', function () {
+    const writer = new GraphSONWriter();
+    assert.strictEqual(writer.write(t.cardinality.set), '{"@type":"g:Cardinality","@value":"set"}');
+  });
   it('should write P', function () {
     const writer = new GraphSONWriter();
     const expected = JSON.stringify({"@type":"g:P","@value":{"predicate":"and","value":[


[tinkerpop] 02/12: Refactor of RemoteStrategy apply()

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 4b5d25aa23b4ab848d9361a5504093ec0f3afe16
Author: Matthew Allen <ma...@runbox.com>
AuthorDate: Fri Aug 24 16:14:29 2018 +0100

    Refactor of RemoteStrategy apply()
---
 .../javascript/gremlin-javascript/lib/driver/remote-connection.js    | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
index d93d89b..96db161 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
@@ -74,9 +74,8 @@ class RemoteStrategy extends TraversalStrategy {
     let args = null;
 
     // check if the last instruction is an eval statement
-    const bytecode = traversal.getBytecode();
-    if (bytecode.stepInstructions.length && bytecode.stepInstructions[bytecode.stepInstructions.length-1][0] === 'eval') {
-      const script = traversal.getBytecode().toScript();
+    if (instructions.stepInstructions.length && instructions.stepInstructions[instructions.stepInstructions.length-1][0] === 'eval') {
+      const script = instructions.toScript();
       op = 'eval';
       processor = '';
       args = {


[tinkerpop] 01/12: Initial Commit for TINKERPOP-1959 solution.

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit ef34c12c7bf84cc812db8fe55bb09d594c84cc35
Author: Matthew Allen <ma...@runbox.com>
AuthorDate: Thu Aug 23 15:48:36 2018 +0100

    Initial Commit for TINKERPOP-1959 solution.
---
 .../glv/GraphTraversalSource.template              |  13 +++
 gremlin-javascript/glv/TraversalSource.template    |  16 +++-
 .../lib/driver/driver-remote-connection.js         |  29 ++++--
 .../lib/driver/remote-connection.js                |  28 +++++-
 .../gremlin-javascript/lib/process/bytecode.js     |  69 +++++++++++++-
 .../lib/process/graph-traversal.js                 |  13 +++
 .../gremlin-javascript/lib/process/traversal.js    |  16 +++-
 .../test/integration/traversal-test.js             |  18 ++++
 .../gremlin-javascript/test/unit/eval-test.js      | 104 +++++++++++++++++++++
 .../gremlin/server/gremlin-server-integration.yaml |   1 +
 10 files changed, 291 insertions(+), 16 deletions(-)

diff --git a/gremlin-javascript/glv/GraphTraversalSource.template b/gremlin-javascript/glv/GraphTraversalSource.template
index 58be16c..3f8e715 100644
--- a/gremlin-javascript/glv/GraphTraversalSource.template
+++ b/gremlin-javascript/glv/GraphTraversalSource.template
@@ -104,6 +104,19 @@ class GraphTraversal extends Traversal {
     return this;
   }
   <% } %>
+
+
+  /**
+   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
+   * then the bytecode instructions will be converted to a script and sent.
+   * @param {string} gremlinScript The script to send to server
+   * @param {array} bindings Map of bindings
+   * @param {*} options Options to configure the script sending
+   */
+  eval(script, bindings) {
+    this.bytecode.addStep('eval', [ script, bindings ]);
+    return this._applyStrategies().then(() => this._getNext());
+  }
 }
 
 function callOnEmptyTraversal(fnName, args) {
diff --git a/gremlin-javascript/glv/TraversalSource.template b/gremlin-javascript/glv/TraversalSource.template
index 6965110..6afe868 100644
--- a/gremlin-javascript/glv/TraversalSource.template
+++ b/gremlin-javascript/glv/TraversalSource.template
@@ -79,15 +79,29 @@ class Traversal {
   }
 
   /**
+   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
+   * then the bytecode instructions will be converted to a script and sent.
+   * @param {string} gremlinScript The script to send to server
+   * @param {array} bindings Map of bindings
+   * @param {*} options Options to configure the script sending
+   */
+  eval(script, bindings) {
+    this.bytecode.addStep('eval', [ script, bindings ]);
+    return this._applyStrategies().then(() => this._getNext());
+  }
+
+  /**
    * Synchronous iterator of traversers including
    * @private
    */
   _getNext() {
     while (this.traversers && this._traversersIteratorIndex < this.traversers.length) {
       let traverser = this.traversers[this._traversersIteratorIndex];
-      if (traverser.bulk > 0) {
+      if (traverser.bulk && traverser.bulk > 0) {
         traverser.bulk--;
         return { value: traverser.object, done: false };
+      } else if (traverser.bulk === undefined) {
+        return { value: traverser, done: true }
       }
       this._traversersIteratorIndex++;
     }
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
index ef0242c..fb66aae 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
@@ -107,7 +107,7 @@ class DriverRemoteConnection extends RemoteConnection {
   }
 
   /** @override */
-  submit(bytecode, op, args, requestId) {
+  submit(bytecode, op, args, requestId, processor) {
     return this.open().then(() => new Promise((resolve, reject) => {
       if (requestId === null || requestId === undefined) {
         requestId = utils.getUuid();
@@ -116,27 +116,38 @@ class DriverRemoteConnection extends RemoteConnection {
           result: null
         };
       }
-      const message = bufferFromString(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args)));
+
+      const message = bufferFromString(this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor)));
       this._ws.send(message);
     }));
   }
 
-  _getRequest(id, bytecode, op, args) {
+  _getRequest(id, bytecode, op, args, processor) {
     if (args) {
       args = this._adaptArgs(args);
     }
-
+    
     return ({
       'requestId': { '@type': 'g:UUID', '@value': id },
       'op': op || 'bytecode',
-      'processor': 'traversal',
-      'args': args || {
-        'gremlin': this._writer.adaptObject(bytecode),
-        'aliases': { 'g': this.traversalSource }
-      }
+      // if using op eval need to ensure processor stays unset if caller didn't set it.
+      'processor': (!processor && op !== 'eval') ? 'traversal' : processor,
+      'args': this._getArgs(args || {
+          'gremlin': this._writer.adaptObject(bytecode)
+        },
+        op
+      )
     });
   }
 
+  _getArgs(args, op) {
+    if (args.aliases === undefined) {
+      args.aliases = { 'g': this.traversalSource };
+    }
+
+    return args;
+  }
+
   _handleMessage(data) {
     const response = this._reader.read(JSON.parse(data.toString()));
     if (response.requestId === null || response.requestId === undefined) {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
index be6f962..d93d89b 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
@@ -34,11 +34,12 @@ class RemoteConnection {
    * @abstract
    * @param {Bytecode} bytecode
    * @param {String} op Operation to perform, defaults to bytecode.
-   * @param {Object} args The arguments for the operation. Defaults to an associative array containing values for "aliases" and "gremlin" keyss.
+   * @param {Object} args The arguments for the operation. Defaults to an associative array containing values for "aliases" and "gremlin" keys.
    * @param {String} requestId A requestId for the current request. If none provided then a requestId is generated internally.
+   * @param {String} processor The processor to use on the connection.
    * @returns {Promise}
    */
-  submit(bytecode, op, args, requestId) {
+  submit(bytecode, op, args, requestId, processor) {
     throw new Error('submit() was not implemented');
   };
 }
@@ -66,7 +67,28 @@ class RemoteStrategy extends TraversalStrategy {
     if (traversal.traversers) {
       return Promise.resolve();
     }
-    return this.connection.submit(traversal.getBytecode()).then(function (remoteTraversal) {
+
+    let instructions = traversal.getBytecode();
+    let op = 'bytecode';
+    let processor = 'traversal';
+    let args = null;
+
+    // check if the last instruction is an eval statement
+    const bytecode = traversal.getBytecode();
+    if (bytecode.stepInstructions.length && bytecode.stepInstructions[bytecode.stepInstructions.length-1][0] === 'eval') {
+      const script = traversal.getBytecode().toScript();
+      op = 'eval';
+      processor = '';
+      args = {
+        'gremlin': script.script,
+        'bindings': script.bindings,
+        'language': 'gremlin-groovy',
+        'accept': 'application/json',
+      };
+      instructions = null;
+    }
+
+    return this.connection.submit(instructions, op, args, null, processor).then(function (remoteTraversal) {
       traversal.sideEffects = remoteTraversal.sideEffects;
       traversal.traversers = remoteTraversal.traversers;
     });
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
index 0f5ba15..fe96568 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
@@ -91,8 +91,73 @@ class Bytecode {
       (this.stepInstructions.length   > 0 ? JSON.stringify(this.stepInstructions) : '')
     );
   }
-}
 
+  /**
+   * Returns a script representations of the step instructions that can be used by standard eval operation.
+   * @returns {Object} An object containing a script string and bindings map.
+   */
+  toScript() {
+    let bindings = {};
+    let script = 'g';
+    let length = this.stepInstructions.length;
+
+    // if eval was passed a script then simply execute the given script.
+    if (this.stepInstructions[length - 1][0] === 'eval'
+      && this.stepInstructions[length - 1][1] !== undefined
+      && this.stepInstructions[length - 1][1] !== null
+    ) {
+      return {
+        script: this.stepInstructions[length - 1][1],
+        bindings: this.stepInstructions[length - 1][2]
+      }
+    }
+
+    if (this.stepInstructions[length - 1][0] === 'eval') {
+      this.stepInstructions.pop();
+      length = this.stepInstructions.length;
+    }
 
+    // build the script from the glv instructions.
+    let paramIdx = 1;
+    for (let i = 0; i < length; i++) {
+      const params = this.stepInstructions[i].slice(1);
+      script = script + '.' + this.stepInstructions[i][0] + '(';
+
+      if (params.length) {
+        for (let k = 0; k < params.length; k++) {
+          if (k > 0) {
+            script = script + ', ';
+          }
+
+          if (Object(params[k]) === params[k]) {
+            script = script + params[k].toString();
+          } else {
+            const prop = `p${paramIdx++}`;
+            script = script + prop;
+            
+            if (typeof params[k] === 'number') {
+              if (Number.isInteger(params[k])) {
+                bindings[prop] = Number.parseInt(params[k]);
+              } else {
+                bindings[prop] = Number.parseFloat(params[k]);
+              }
+            } else if (params[k] === undefined) {
+              bindings[prop] = null;
+            } else {
+              bindings[prop] = params[k];
+            }
+          }
+        }
+      }
+
+      script = script + ')';
+    }
+    
+    return {
+      script,
+      bindings
+    };
+  }
+}
 
-module.exports = Bytecode;
\ No newline at end of file
+module.exports = Bytecode;
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
index edeb2cb..aa0259b 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
@@ -1132,6 +1132,19 @@ class GraphTraversal extends Traversal {
     return this;
   }
   
+
+
+  /**
+   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
+   * then the bytecode instructions will be converted to a script and sent.
+   * @param {string} gremlinScript The script to send to server
+   * @param {array} bindings Map of bindings
+   * @param {*} options Options to configure the script sending
+   */
+  eval(script, bindings) {
+    this.bytecode.addStep('eval', [ script, bindings ]);
+    return this._applyStrategies().then(() => this._getNext());
+  }
 }
 
 function callOnEmptyTraversal(fnName, args) {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
index d39ccf0..d8a0761 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
@@ -79,15 +79,29 @@ class Traversal {
   }
 
   /**
+   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
+   * then the bytecode instructions will be converted to a script and sent.
+   * @param {string} gremlinScript The script to send to server
+   * @param {array} bindings Map of bindings
+   * @param {*} options Options to configure the script sending
+   */
+  eval(script, bindings) {
+    this.bytecode.addStep('eval', [ script, bindings ]);
+    return this._applyStrategies().then(() => this._getNext());
+  }
+
+  /**
    * Synchronous iterator of traversers including
    * @private
    */
   _getNext() {
     while (this.traversers && this._traversersIteratorIndex < this.traversers.length) {
       let traverser = this.traversers[this._traversersIteratorIndex];
-      if (traverser.bulk > 0) {
+      if (traverser.bulk && traverser.bulk > 0) {
         traverser.bulk--;
         return { value: traverser.object, done: false };
+      } else if (traverser.bulk === undefined) {
+        return { value: traverser, done: true }
       }
       this._traversersIteratorIndex++;
     }
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
index 920d998..9d5af16 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
@@ -66,4 +66,22 @@ describe('Traversal', function () {
         });
     });
   });
+  describe('#eval()', function() {
+    it('should submit the traversal as a script and return a result', function() {
+      var g = new Graph().traversal().withRemote(connection);
+      return g.V().count().eval().then(function (item) {
+        assert.ok(item);
+        assert.strictEqual(item.done, true);
+        assert.strictEqual(typeof item.value, 'number');
+      });
+    });
+
+    it('should submit a script and bindings and return a result', function() {
+      var g = new Graph().traversal().withRemote(connection);
+      return g.V().eval('g.V().has(\'name\', name)', { name: 'marko' }).then(function (item) {
+        assert.ok(item);
+        assert.ok(item.value instanceof Vertex);
+      });
+    });
+  });
 });
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js
new file mode 100644
index 0000000..c3c87fb
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js
@@ -0,0 +1,104 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+'use strict';
+
+const assert = require('assert');
+const expect = require('chai').expect;
+const graph = require('../../lib/structure/graph');
+const t = require('../../lib/process/traversal');
+const TraversalStrategies = require('../../lib/process/traversal-strategy').TraversalStrategies;
+const Bytecode = require('../../lib/process/bytecode');
+
+describe('Traversal', function () {
+
+  describe('#getBytecode#toScript()', function () {
+    it('should add steps and produce valid script representation', function () {
+      const g = new graph.Graph().traversal();
+      const script = g.V().out('created').getBytecode().toScript();
+      assert.ok(script);
+      assert.strictEqual(script.script, 'g.V().out(p1)');
+    });
+
+    it('should add steps and produce valid script representation with parameter bindings', function () {
+      const g = new graph.Graph().traversal();
+      const script = g.addV('name', 'Lilac').getBytecode().toScript();
+      assert.ok(script);
+      assert.strictEqual(script.script, 'g.addV(p1, p2)');
+      assert.ok(script.bindings);
+      assert.deepStrictEqual(script.bindings, { p1: 'name', p2: 'Lilac' });
+    });
+
+    it('should add steps containing enum and produce valid script representation', function () {
+      const g = new graph.Graph().traversal();
+      const script = g.V().order().by('age', t.order.decr).getBytecode().toScript();
+      assert.ok(script);
+      assert.strictEqual(script.script, 'g.V().order().by(p1, decr)');
+    });
+
+    it('should add steps containing a predicate and produce valid script representation', function () {
+      const g = new graph.Graph().traversal();
+      const script = g.V().hasLabel('person').has('age', t.P.gt(30)).getBytecode().toScript();
+      assert.ok(script);
+      assert.strictEqual(script.script, 'g.V().hasLabel(p1).has(p2, gt(30))');
+    });
+
+    it('should take a script and return that script along with passed in bindings', function () {
+      const g = new graph.Graph().traversal();
+      const bytecode = g.addV('name', 'Lilac').getBytecode();
+      const script = bytecode.addStep('eval', [ 
+        'g.addV(\'name\', name).property(\'created\', date)',
+        { name: 'Lilac', created: '2018-01-01T00:00:00.000z' }
+      ]).toScript();
+      assert.ok(script);
+      assert.strictEqual(script.script, 'g.addV(\'name\', name).property(\'created\', date)');
+      assert.deepStrictEqual(script.bindings, { name: 'Lilac', created: '2018-01-01T00:00:00.000z' });
+    });
+  });
+
+  describe('#eval()', function () {
+    it('should apply the strategies and return a Promise with the iterator item', function () {
+      const strategyMock = {
+        apply: function (traversal) {
+          traversal.traversers = [ new t.Traverser(1, 1), new t.Traverser(2, 1) ];
+          return Promise.resolve();
+        }
+      };
+      const strategies = new TraversalStrategies();
+      strategies.addStrategy(strategyMock);
+      const traversal = new t.Traversal(null, strategies, new Bytecode());
+      return traversal.eval(null, null, null)
+        .then(function (item) {
+          assert.strictEqual(item.value, 1);
+          assert.strictEqual(item.done, false);
+          return traversal.eval(null, null, null);
+        })
+        .then(function (item) {
+          assert.strictEqual(item.value, 2);
+          assert.strictEqual(item.done, false);
+          return traversal.eval(null, null, null);
+        })
+        .then(function (item) {
+          assert.strictEqual(item.value, null);
+          assert.strictEqual(item.done, true);
+          return traversal.eval(null, null, null);
+        });
+    });
+  });
+});
diff --git a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml
index 4e6cf9a..f4d508a 100644
--- a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml
+++ b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml
@@ -42,6 +42,7 @@ serializers:
   - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0] }}
 processors:
   - { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
+  - { className: org.apache.tinkerpop.gremlin.server.op.standard.StandardOpProcessor, config: { maxParameters: 64 }}
 metrics: {
   slf4jReporter: {enabled: true, interval: 180000}}
 strictTransactionManagement: false


[tinkerpop] 10/12: TINKERPOP-1959 Refactored request arg serialization to be more general

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit cfa6c0425d928bf06f3f54b9379574ca8f22f52a
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Fri Oct 5 09:42:37 2018 -0400

    TINKERPOP-1959 Refactored request arg serialization to be more general
---
 .../lib/driver/driver-remote-connection.js         | 25 +++++++++++-----------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
index 5b84b04..a1d3d42 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
@@ -125,9 +125,9 @@ class DriverRemoteConnection extends RemoteConnection {
 
   _getRequest(id, bytecode, op, args, processor) {
     if (args) {
-      args = this._adaptArgs(args);
+      args = this._adaptArgs(args, true);
     }
-    
+
     return ({
       'requestId': { '@type': 'g:UUID', '@value': id },
       'op': op || 'bytecode',
@@ -214,24 +214,23 @@ class DriverRemoteConnection extends RemoteConnection {
    * @returns {Object}
    * @private
    */
-  _adaptArgs(args) {
-    if (Array.isArray(args)) {
-      return args.map(val => this._adaptArgs(val));
-    }
-
-    if (args instanceof t.EnumValue) {
-       return this._writer.adaptObject(args);
-    }
-
+  _adaptArgs(args, protocolLevel) {
     if (args instanceof Object) {
       let newObj = {};
       Object.keys(args).forEach((key) => {
-        newObj[key] = this._adaptArgs(args[key]);
+        // bindings key (at the protocol-level needs special handling. without this, it wraps the generated Map
+        // in another map for types like EnumValue. Could be a nicer way to do this but for now it's solving the
+        // problem with script submission of non JSON native types
+        if (protocolLevel && key === 'bindings')
+          newObj[key] = this._adaptArgs(args[key], false);
+        else
+          newObj[key] = this._writer.adaptObject(args[key]);
       });
+
       return newObj;
     }
 
-    return this._writer.adaptObject(args);
+    return args;
   }
 
   /**


[tinkerpop] 05/12: Client and Translator classes for better handling of scripts

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit a72c6fb8e939b31b2a779aa743daad762d0e5fe6
Author: Matthew Allen <ma...@runbox.com>
AuthorDate: Sat Sep 1 07:53:13 2018 +0100

    Client and Translator classes for better handling of scripts
---
 .../glv/GraphTraversalSource.template              |  11 ---
 gremlin-javascript/glv/TraversalSource.template    |  11 ---
 .../main/javascript/gremlin-javascript/index.js    |   6 +-
 .../gremlin-javascript/lib/driver/client.js        |  65 +++++++++++++
 .../lib/driver/driver-remote-connection.js         |  17 +---
 .../lib/driver/remote-connection.js                |  21 +----
 .../gremlin-javascript/lib/process/bytecode.js     |  67 -------------
 .../lib/process/graph-traversal.js                 |  11 ---
 .../gremlin-javascript/lib/process/translator.js   |  91 ++++++++++++++++++
 .../gremlin-javascript/lib/process/traversal.js    |  11 ---
 .../javascript/gremlin-javascript/test/helper.js   |   5 +
 .../test/integration/client-tests.js               |  65 +++++++++++++
 .../test/integration/traversal-test.js             |  18 ----
 .../gremlin-javascript/test/unit/eval-test.js      | 104 ---------------------
 .../test/unit/translator-test.js                   |  61 ++++++++++++
 15 files changed, 297 insertions(+), 267 deletions(-)

diff --git a/gremlin-javascript/glv/GraphTraversalSource.template b/gremlin-javascript/glv/GraphTraversalSource.template
index 1d3dd5d..58be16c 100644
--- a/gremlin-javascript/glv/GraphTraversalSource.template
+++ b/gremlin-javascript/glv/GraphTraversalSource.template
@@ -84,17 +84,6 @@ class GraphTraversalSource {
     return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b);
   }
   <% } %>
-
-
-  /**
-   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
-   * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} script The script to send to server
-   * @param {array} bindings Map of bindings
-   */
-  eval(script, bindings) {
-    return (new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), new Bytecode(this.bytecode))).eval(script, bindings);
-  }
 }
 
 /**
diff --git a/gremlin-javascript/glv/TraversalSource.template b/gremlin-javascript/glv/TraversalSource.template
index 9824273..f3c7795 100644
--- a/gremlin-javascript/glv/TraversalSource.template
+++ b/gremlin-javascript/glv/TraversalSource.template
@@ -79,17 +79,6 @@ class Traversal {
   }
 
   /**
-   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
-   * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} script The script to send to server
-   * @param {array} bindings Map of bindings
-   */
-  eval(script, bindings) {
-    this.bytecode.addStep('eval', [ script, bindings ]);
-    return this._applyStrategies().then(() => this._getNext());
-  }
-
-  /**
    * Synchronous iterator of traversers including
    * @private
    */
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
index c2e810d..ffc7f0c 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
@@ -29,8 +29,10 @@ const graph = require('./lib/structure/graph');
 const gs = require('./lib/structure/io/graph-serializer');
 const rc = require('./lib/driver/remote-connection');
 const Bytecode = require('./lib/process/bytecode');
+const Translator = require('./lib/process/translator');
 const utils = require('./lib/utils');
 const DriverRemoteConnection = require('./lib/driver/driver-remote-connection');
+const Client = require('./lib/driver/client');
 const Authenticator = require('./lib/driver/auth/authenticator');
 const PlainTextSaslAuthenticator = require('./lib/driver/auth/plain-text-sasl-authenticator');
 
@@ -40,6 +42,7 @@ module.exports = {
     RemoteStrategy: rc.RemoteStrategy,
     RemoteTraversal: rc.RemoteTraversal,
     DriverRemoteConnection: DriverRemoteConnection,
+    Client: Client,
     auth: {
       Authenticator: Authenticator,
       PlainTextSaslAuthenticator: PlainTextSaslAuthenticator
@@ -66,7 +69,8 @@ module.exports = {
     t: t.t,
     GraphTraversal: gt.GraphTraversal,
     GraphTraversalSource: gt.GraphTraversalSource,
-    statics: gt.statics
+    statics: gt.statics,
+    Translator: Translator
   },
   structure: {
     io: {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
new file mode 100644
index 0000000..89d9347
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
@@ -0,0 +1,65 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+'use strict';
+
+const DriverRemoteConnection = require('./driver-remote-connection');
+const Bytecode = require('../process/bytecode');
+
+class Client extends DriverRemoteConnection {
+  /**
+   * Creates a new instance of DriverRemoteConnection.
+   * @param {String} url The resource uri.
+   * @param {Object} [options] The connection options.
+   * @param {Array} [options.ca] Trusted certificates.
+   * @param {String|Array|Buffer} [options.cert] The certificate key.
+   * @param {String} [options.mimeType] The mime type to use.
+   * @param {String|Buffer} [options.pfx] The private key, certificate, and CA certs.
+   * @param {GraphSONReader} [options.reader] The reader to use.
+   * @param {Boolean} [options.rejectUnauthorized] Determines whether to verify or not the server certificate.
+   * @param {String} [options.traversalSource] The traversal source. Defaults to: 'g'.
+   * @param {GraphSONWriter} [options.writer] The writer to use.
+   * @param {Authenticator} [options.authenticator] The authentication handler to use.
+   * @constructor
+   */
+  constructor(url, options) {
+    super(url, options);
+  }
+
+  /** override */
+  submit(message, bindings) {
+    if (typeof message === 'string' || message instanceof String) {
+      const args = {
+        'gremlin': message,
+        'bindings': bindings,
+        'language': 'gremlin-groovy',
+        'accept': 'application/json',
+        'aliases': { 'g': this.traversalSource }
+      };
+
+      return super.submit(null, 'eval', args, null, '');
+    }
+
+    if (message instanceof Bytecode) {
+      return super.submit(message);
+    }
+  }
+  
+}
+
+module.exports = Client;
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
index fb66aae..81d5124 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
@@ -132,22 +132,13 @@ class DriverRemoteConnection extends RemoteConnection {
       'op': op || 'bytecode',
       // if using op eval need to ensure processor stays unset if caller didn't set it.
       'processor': (!processor && op !== 'eval') ? 'traversal' : processor,
-      'args': this._getArgs(args || {
-          'gremlin': this._writer.adaptObject(bytecode)
-        },
-        op
-      )
+      'args': args || {
+          'gremlin': this._writer.adaptObject(bytecode),
+          'aliases': { 'g': this.traversalSource }
+        }
     });
   }
 
-  _getArgs(args, op) {
-    if (args.aliases === undefined) {
-      args.aliases = { 'g': this.traversalSource };
-    }
-
-    return args;
-  }
-
   _handleMessage(data) {
     const response = this._reader.read(JSON.parse(data.toString()));
     if (response.requestId === null || response.requestId === undefined) {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
index 96db161..c675c42 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
@@ -68,26 +68,7 @@ class RemoteStrategy extends TraversalStrategy {
       return Promise.resolve();
     }
 
-    let instructions = traversal.getBytecode();
-    let op = 'bytecode';
-    let processor = 'traversal';
-    let args = null;
-
-    // check if the last instruction is an eval statement
-    if (instructions.stepInstructions.length && instructions.stepInstructions[instructions.stepInstructions.length-1][0] === 'eval') {
-      const script = instructions.toScript();
-      op = 'eval';
-      processor = '';
-      args = {
-        'gremlin': script.script,
-        'bindings': script.bindings,
-        'language': 'gremlin-groovy',
-        'accept': 'application/json',
-      };
-      instructions = null;
-    }
-
-    return this.connection.submit(instructions, op, args, null, processor).then(function (remoteTraversal) {
+    return this.connection.submit(traversal.getBytecode()).then(function (remoteTraversal) {
       traversal.sideEffects = remoteTraversal.sideEffects;
       traversal.traversers = remoteTraversal.traversers;
     });
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
index fe96568..e7fdd40 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
@@ -91,73 +91,6 @@ class Bytecode {
       (this.stepInstructions.length   > 0 ? JSON.stringify(this.stepInstructions) : '')
     );
   }
-
-  /**
-   * Returns a script representations of the step instructions that can be used by standard eval operation.
-   * @returns {Object} An object containing a script string and bindings map.
-   */
-  toScript() {
-    let bindings = {};
-    let script = 'g';
-    let length = this.stepInstructions.length;
-
-    // if eval was passed a script then simply execute the given script.
-    if (this.stepInstructions[length - 1][0] === 'eval'
-      && this.stepInstructions[length - 1][1] !== undefined
-      && this.stepInstructions[length - 1][1] !== null
-    ) {
-      return {
-        script: this.stepInstructions[length - 1][1],
-        bindings: this.stepInstructions[length - 1][2]
-      }
-    }
-
-    if (this.stepInstructions[length - 1][0] === 'eval') {
-      this.stepInstructions.pop();
-      length = this.stepInstructions.length;
-    }
-
-    // build the script from the glv instructions.
-    let paramIdx = 1;
-    for (let i = 0; i < length; i++) {
-      const params = this.stepInstructions[i].slice(1);
-      script = script + '.' + this.stepInstructions[i][0] + '(';
-
-      if (params.length) {
-        for (let k = 0; k < params.length; k++) {
-          if (k > 0) {
-            script = script + ', ';
-          }
-
-          if (Object(params[k]) === params[k]) {
-            script = script + params[k].toString();
-          } else {
-            const prop = `p${paramIdx++}`;
-            script = script + prop;
-            
-            if (typeof params[k] === 'number') {
-              if (Number.isInteger(params[k])) {
-                bindings[prop] = Number.parseInt(params[k]);
-              } else {
-                bindings[prop] = Number.parseFloat(params[k]);
-              }
-            } else if (params[k] === undefined) {
-              bindings[prop] = null;
-            } else {
-              bindings[prop] = params[k];
-            }
-          }
-        }
-      }
-
-      script = script + ')';
-    }
-    
-    return {
-      script,
-      bindings
-    };
-  }
 }
 
 module.exports = Bytecode;
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
index c73405e..edeb2cb 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
@@ -172,17 +172,6 @@ class GraphTraversalSource {
     return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b);
   }
   
-
-
-  /**
-   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
-   * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} script The script to send to server
-   * @param {array} bindings Map of bindings
-   */
-  eval(script, bindings) {
-    return (new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), new Bytecode(this.bytecode))).eval(script, bindings);
-  }
 }
 
 /**
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js
new file mode 100644
index 0000000..dfd4b69
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js
@@ -0,0 +1,91 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+'use strict';
+
+/**
+ * Class to translate glv bytecode steps into executable Gremlin-Groovy script
+ */
+class Translator {
+  constructor(traversalSource) {
+    this._traversalSource = traversalSource;
+  }
+
+  getTraversalSource() {
+    return this._traversalSource;
+  }
+
+  getTargetLanguage() {
+    return "gremlin-groovy";
+  }
+
+  of(traversalSource) {
+    this._traversalSource = traversalSource;
+  }
+
+  /**
+   * Returns a script representation of the given bytecode instructions.
+   * @param {Object} bytecode The bytecode object containing step instructions.
+   * @returns {string} Gremlin-Groovy script
+   */
+  translate(bytecode) {
+    let script = this._traversalSource;
+    let instructions = bytecode.stepInstructions;
+
+    // build the script from the glv instructions.
+    for (let i = 0; i < instructions.length; i++) {
+      const params = instructions[i].slice(1);
+      script += '.' + instructions[i][0] + '(';
+
+      if (params.length) {
+        for (let k = 0; k < params.length; k++) {
+          if (k > 0) {
+            script += ', ';
+          }
+
+          if (Object(params[k]) === params[k]) {
+            if (params[k].toString() === '[object Object]') {
+              Object.keys(params[k]).forEach(function(key, index) {
+                if (index > 0) script += ', ';
+                script += '(\'' + key + '\', ';
+                if (params[k][key] instanceof String || typeof params[k][key] === 'string') {
+                  script += '\'' + params[k][key] + '\'';
+                } else {
+                  script += params[k][key];
+                }
+                script += ')';
+              });
+            } else {
+              script += params[k].toString();
+            }
+          } else if (params[k] === undefined) {
+            script += '';
+          } else {
+            script += '\'' + params[k] + '\'';
+          }
+        }
+      }
+
+      script += ')';
+    }
+    
+    return script;
+  }
+}
+
+module.exports = Translator;
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
index 9b88232..5ec2db5 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
@@ -79,17 +79,6 @@ class Traversal {
   }
 
   /**
-   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
-   * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} script The script to send to server
-   * @param {array} bindings Map of bindings
-   */
-  eval(script, bindings) {
-    this.bytecode.addStep('eval', [ script, bindings ]);
-    return this._applyStrategies().then(() => this._getNext());
-  }
-
-  /**
    * Synchronous iterator of traversers including
    * @private
    */
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
index 899a8ad..b2a61d2 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
@@ -24,6 +24,7 @@
 const os = require('os');
 
 const DriverRemoteConnection = require('../lib/driver/driver-remote-connection');
+const Client = require('../lib/driver/client');
 const PlainTextSaslAuthenticator = require('../lib/driver/auth/plain-text-sasl-authenticator');
 
 exports.getConnection = function getConnection(traversalSource) {
@@ -37,4 +38,8 @@ exports.getSecureConnectionWithPlainTextSaslAuthenticator = function getConnecti
     authenticator: authenticator, 
     rejectUnauthorized: false 
   });
+};
+
+exports.getClient = function getClient(traversalSource) {
+  return new Client('ws://localhost:45940/gremlin', { traversalSource: traversalSource });
 };
\ No newline at end of file
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
new file mode 100644
index 0000000..83f4baa
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-tests.js
@@ -0,0 +1,65 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+'use strict';
+
+const assert = require('assert');
+const Bytecode = require('../../lib/process/bytecode');
+const graphModule = require('../../lib/structure/graph');
+const helper = require('../helper');
+
+let connection;
+
+describe('Client', function () {
+  before(function () {
+    connection = helper.getClient('gmodern');
+    return connection.open();
+  });
+  after(function () {
+    return connection.close();
+  });
+  describe('#submit()', function () {
+    it('should send bytecode', function () {
+      return connection.submit(new Bytecode().addStep('V', []).addStep('tail', []))
+        .then(function (response) {
+          assert.ok(response);
+          assert.ok(response.traversers);
+          assert.strictEqual(response.traversers.length, 1);
+          assert.ok(response.traversers[0].object instanceof graphModule.Vertex);
+        });
+    });
+    it('should send and parse a script', function () {
+      return connection.submit('g.V().tail()')
+        .then(function (response) {
+          assert.ok(response);
+          assert.ok(response.traversers);
+          assert.strictEqual(response.traversers.length, 1);
+          assert.ok(response.traversers[0] instanceof graphModule.Vertex);
+        });
+    });
+    it('should send and parse a script with bindings', function () {
+      return connection.submit('x + x', {x: 3})
+        .then(function (response) {
+          assert.ok(response);
+          assert.ok(response.traversers);
+          assert.strictEqual(response.traversers[0], 6);
+        });
+    });
+  });
+});
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
index cfdc4f0..920d998 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
@@ -66,22 +66,4 @@ describe('Traversal', function () {
         });
     });
   });
-  describe('#eval()', function() {
-    it('should submit the traversal as a script and return a result', function() {
-      var g = new Graph().traversal().withRemote(connection);
-      return g.V().count().eval().then(function (item) {
-        assert.ok(item);
-        assert.strictEqual(item.done, true);
-        assert.strictEqual(typeof item.value, 'number');
-      });
-    });
-
-    it('should submit a script and bindings and return a result', function() {
-      var g = new Graph().traversal().withRemote(connection);
-      return g.eval('g.V(v1)', { v1: 1 }).then(function (item) {
-        assert.ok(item);
-        assert.ok(item.value instanceof Vertex);
-      });
-    });
-  });
 });
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js
deleted file mode 100644
index c3c87fb..0000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-'use strict';
-
-const assert = require('assert');
-const expect = require('chai').expect;
-const graph = require('../../lib/structure/graph');
-const t = require('../../lib/process/traversal');
-const TraversalStrategies = require('../../lib/process/traversal-strategy').TraversalStrategies;
-const Bytecode = require('../../lib/process/bytecode');
-
-describe('Traversal', function () {
-
-  describe('#getBytecode#toScript()', function () {
-    it('should add steps and produce valid script representation', function () {
-      const g = new graph.Graph().traversal();
-      const script = g.V().out('created').getBytecode().toScript();
-      assert.ok(script);
-      assert.strictEqual(script.script, 'g.V().out(p1)');
-    });
-
-    it('should add steps and produce valid script representation with parameter bindings', function () {
-      const g = new graph.Graph().traversal();
-      const script = g.addV('name', 'Lilac').getBytecode().toScript();
-      assert.ok(script);
-      assert.strictEqual(script.script, 'g.addV(p1, p2)');
-      assert.ok(script.bindings);
-      assert.deepStrictEqual(script.bindings, { p1: 'name', p2: 'Lilac' });
-    });
-
-    it('should add steps containing enum and produce valid script representation', function () {
-      const g = new graph.Graph().traversal();
-      const script = g.V().order().by('age', t.order.decr).getBytecode().toScript();
-      assert.ok(script);
-      assert.strictEqual(script.script, 'g.V().order().by(p1, decr)');
-    });
-
-    it('should add steps containing a predicate and produce valid script representation', function () {
-      const g = new graph.Graph().traversal();
-      const script = g.V().hasLabel('person').has('age', t.P.gt(30)).getBytecode().toScript();
-      assert.ok(script);
-      assert.strictEqual(script.script, 'g.V().hasLabel(p1).has(p2, gt(30))');
-    });
-
-    it('should take a script and return that script along with passed in bindings', function () {
-      const g = new graph.Graph().traversal();
-      const bytecode = g.addV('name', 'Lilac').getBytecode();
-      const script = bytecode.addStep('eval', [ 
-        'g.addV(\'name\', name).property(\'created\', date)',
-        { name: 'Lilac', created: '2018-01-01T00:00:00.000z' }
-      ]).toScript();
-      assert.ok(script);
-      assert.strictEqual(script.script, 'g.addV(\'name\', name).property(\'created\', date)');
-      assert.deepStrictEqual(script.bindings, { name: 'Lilac', created: '2018-01-01T00:00:00.000z' });
-    });
-  });
-
-  describe('#eval()', function () {
-    it('should apply the strategies and return a Promise with the iterator item', function () {
-      const strategyMock = {
-        apply: function (traversal) {
-          traversal.traversers = [ new t.Traverser(1, 1), new t.Traverser(2, 1) ];
-          return Promise.resolve();
-        }
-      };
-      const strategies = new TraversalStrategies();
-      strategies.addStrategy(strategyMock);
-      const traversal = new t.Traversal(null, strategies, new Bytecode());
-      return traversal.eval(null, null, null)
-        .then(function (item) {
-          assert.strictEqual(item.value, 1);
-          assert.strictEqual(item.done, false);
-          return traversal.eval(null, null, null);
-        })
-        .then(function (item) {
-          assert.strictEqual(item.value, 2);
-          assert.strictEqual(item.done, false);
-          return traversal.eval(null, null, null);
-        })
-        .then(function (item) {
-          assert.strictEqual(item.value, null);
-          assert.strictEqual(item.done, true);
-          return traversal.eval(null, null, null);
-        });
-    });
-  });
-});
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js
new file mode 100644
index 0000000..b5310bf
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+'use strict';
+
+const assert = require('assert');
+const expect = require('chai').expect;
+const graph = require('../../lib/structure/graph');
+const t = require('../../lib/process/traversal');
+const TraversalStrategies = require('../../lib/process/traversal-strategy').TraversalStrategies;
+const Bytecode = require('../../lib/process/bytecode');
+const Translator = require('../../lib/process/translator');
+
+describe('Translator', function () {
+
+  describe('#translate()', function () {
+    it('should produce valid script representation from bytecode glv steps', function () {
+      const g = new graph.Graph().traversal();
+      const script = new Translator('g').translate(g.V().out('created').getBytecode());
+      assert.ok(script);
+      assert.strictEqual(script, 'g.V().out(\'created\')');
+    });
+
+    it('should produce valid script representation from bytecode glv steps containing parameter bindings', function () {
+      const g = new graph.Graph().traversal();
+      const script = new Translator('g').translate(g.addV({'name': 'Lilac'}).getBytecode());
+      assert.ok(script);
+      assert.strictEqual(script, 'g.addV((\'name\', \'Lilac\'))');
+    });
+
+    it('should produce valid script representation from bytecode glv steps containing enum', function () {
+      const g = new graph.Graph().traversal();
+      const script = new Translator('g').translate(g.V().order().by('age', t.order.decr).getBytecode());
+      assert.ok(script);
+      assert.strictEqual(script, 'g.V().order().by(\'age\', decr)');
+    });
+
+    it('should produce valid script representation from bytecode glv steps containing a predicate', function () {
+      const g = new graph.Graph().traversal();
+      const script = new Translator('g').translate(g.V().hasLabel('person').has('age', t.P.gt(30)).getBytecode());
+      assert.ok(script);
+      assert.strictEqual(script, 'g.V().hasLabel(\'person\').has(\'age\', gt(30))');
+    });
+  });
+});


[tinkerpop] 11/12: TINKERPOP-1959 Minor fixes to upgrade docs

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 0fb7c9eae2330f45e8aadbe632227042cf1fc0e0
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Fri Oct 5 10:37:24 2018 -0400

    TINKERPOP-1959 Minor fixes to upgrade docs
---
 docs/src/upgrade/release-3.2.x-incubating.asciidoc | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index 26a2552..72c0a1c 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -107,7 +107,8 @@ via that same method as the other toy graphs with `TinkerFactory.createGratefulD
 
 ==== Gremlin Javascript Script Submission
 
-Gremlin Javascript can now submit script, with optional bindings, using the Client class:
+Gremlin Javascript can now submit script, with optional bindings, using the `Client` class:
+
 [source,javascript]
 ----
 const gremlin = require('gremlin');
@@ -126,7 +127,7 @@ connection.submit('g.V(vid)', {vid: 1})
     });
 ----
 
-and you can also translate bytecode steps into script
+and also allows translation of bytecode steps into script:
 
 [source,javascript]
 ----


[tinkerpop] 04/12: Fixed issue where eval was added to wrong class in GraphTravesal

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 9f4cfc7bdbcf74fafb73a3a7de31f4fd01a591e6
Author: Matthew Allen <ma...@runbox.com>
AuthorDate: Mon Aug 27 09:52:49 2018 +0100

    Fixed issue where eval was added to wrong class in GraphTravesal
---
 .../glv/GraphTraversalSource.template              | 23 ++++++++++-----------
 .../lib/process/graph-traversal.js                 | 24 ++++++++++------------
 .../gremlin-javascript/lib/process/traversal.js    |  3 +--
 .../test/integration/traversal-test.js             |  2 +-
 4 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/gremlin-javascript/glv/GraphTraversalSource.template b/gremlin-javascript/glv/GraphTraversalSource.template
index e48dd67..1d3dd5d 100644
--- a/gremlin-javascript/glv/GraphTraversalSource.template
+++ b/gremlin-javascript/glv/GraphTraversalSource.template
@@ -84,6 +84,17 @@ class GraphTraversalSource {
     return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b);
   }
   <% } %>
+
+
+  /**
+   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
+   * then the bytecode instructions will be converted to a script and sent.
+   * @param {string} script The script to send to server
+   * @param {array} bindings Map of bindings
+   */
+  eval(script, bindings) {
+    return (new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), new Bytecode(this.bytecode))).eval(script, bindings);
+  }
 }
 
 /**
@@ -104,18 +115,6 @@ class GraphTraversal extends Traversal {
     return this;
   }
   <% } %>
-
-
-  /**
-   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
-   * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} script The script to send to server
-   * @param {array} bindings Map of bindings
-   */
-  eval(script, bindings) {
-    this.bytecode.addStep('eval', [ script, bindings ]);
-    return this._applyStrategies().then(() => this._getNext());
-  }
 }
 
 function callOnEmptyTraversal(fnName, args) {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
index aa0259b..c73405e 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
@@ -172,6 +172,17 @@ class GraphTraversalSource {
     return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b);
   }
   
+
+
+  /**
+   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
+   * then the bytecode instructions will be converted to a script and sent.
+   * @param {string} script The script to send to server
+   * @param {array} bindings Map of bindings
+   */
+  eval(script, bindings) {
+    return (new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), new Bytecode(this.bytecode))).eval(script, bindings);
+  }
 }
 
 /**
@@ -1132,19 +1143,6 @@ class GraphTraversal extends Traversal {
     return this;
   }
   
-
-
-  /**
-   * Send a Gremlin-Groovy script to the server. If a script is not passed in 
-   * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} gremlinScript The script to send to server
-   * @param {array} bindings Map of bindings
-   * @param {*} options Options to configure the script sending
-   */
-  eval(script, bindings) {
-    this.bytecode.addStep('eval', [ script, bindings ]);
-    return this._applyStrategies().then(() => this._getNext());
-  }
 }
 
 function callOnEmptyTraversal(fnName, args) {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
index d8a0761..9b88232 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
@@ -81,9 +81,8 @@ class Traversal {
   /**
    * Send a Gremlin-Groovy script to the server. If a script is not passed in 
    * then the bytecode instructions will be converted to a script and sent.
-   * @param {string} gremlinScript The script to send to server
+   * @param {string} script The script to send to server
    * @param {array} bindings Map of bindings
-   * @param {*} options Options to configure the script sending
    */
   eval(script, bindings) {
     this.bytecode.addStep('eval', [ script, bindings ]);
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
index 9d5af16..cfdc4f0 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js
@@ -78,7 +78,7 @@ describe('Traversal', function () {
 
     it('should submit a script and bindings and return a result', function() {
       var g = new Graph().traversal().withRemote(connection);
-      return g.V().eval('g.V().has(\'name\', name)', { name: 'marko' }).then(function (item) {
+      return g.eval('g.V(v1)', { v1: 1 }).then(function (item) {
         assert.ok(item);
         assert.ok(item.value instanceof Vertex);
       });


[tinkerpop] 06/12: Fix for numbers not being translated correctly in the bytecode translator

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit a59780f7c09de57449aab606c32580455184a7b2
Author: Matthew Allen <ma...@runbox.com>
AuthorDate: Sat Sep 1 08:24:05 2018 +0100

    Fix for numbers not being translated correctly in the bytecode translator
---
 .../main/javascript/gremlin-javascript/lib/process/translator.js   | 2 ++
 .../javascript/gremlin-javascript/test/unit/translator-test.js     | 7 +++++++
 2 files changed, 9 insertions(+)

diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js
index dfd4b69..32c58d7 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js
@@ -75,6 +75,8 @@ class Translator {
             }
           } else if (params[k] === undefined) {
             script += '';
+          } else if (typeof params[k] === 'number') {
+            script += params[k];
           } else {
             script += '\'' + params[k] + '\'';
           }
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js
index b5310bf..f8d4396 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js
@@ -37,6 +37,13 @@ describe('Translator', function () {
       assert.strictEqual(script, 'g.V().out(\'created\')');
     });
 
+    it('should produce valid script representation from bytecode glv steps translating number and text correctly', function () {
+      const g = new graph.Graph().traversal();
+      const script = new Translator('g').translate(g.V(1).out('created').getBytecode());
+      assert.ok(script);
+      assert.strictEqual(script, 'g.V(1).out(\'created\')');
+    });
+
     it('should produce valid script representation from bytecode glv steps containing parameter bindings', function () {
       const g = new graph.Graph().traversal();
       const script = new Translator('g').translate(g.addV({'name': 'Lilac'}).getBytecode());


[tinkerpop] 08/12: Test added to Client to confirm correct handling of non JS native types. Changed script submission to accept GraphSON v2. Reverted TraversalSource template to original. Removed configuration of standardOp Processor. Updated CHANGELOG and upgrade documentation.

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit d12f117cdd9fbdaa2232936fe89c93273c011200
Author: Matthew Allen <ma...@runbox.com>
AuthorDate: Thu Oct 4 20:57:57 2018 +0100

    Test added to Client to confirm correct handling of non JS native types.
    Changed script submission to accept GraphSON v2.
    Reverted TraversalSource template to original.
    Removed configuration of standardOp Processor.
    Updated CHANGELOG and upgrade documentation.
---
 CHANGELOG.asciidoc                                 |  2 ++
 docs/src/upgrade/release-3.2.x-incubating.asciidoc | 41 ++++++++++++++++++++++
 gremlin-javascript/glv/TraversalSource.template    |  4 +--
 .../gremlin-javascript/lib/driver/client.js        |  4 +--
 .../test/integration/client-tests.js               | 16 ++++++++-
 .../gremlin/server/gremlin-server-integration.yaml |  2 +-
 6 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 0a76cc0..21880af 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -413,6 +413,8 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Fixed a bug in JavaScript GLV where DriverRemoteConnection close() method didn't returned a Promise instance.
 * Bumped to Jackson 2.9.6.
 * Sasl Plain Text Authentication added to Gremlin Javascript.
+* Ability to send scripts to server added to Gremlin Javascript.
+* Translator class added to Gremlin Javascript to translate bytecode to script clientside.
 
 [[release-3-2-9]]
 === TinkerPop 3.2.9 (Release Date: May 8, 2018)
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index 46f5780..26a2552 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -105,6 +105,47 @@ packaged dataset that needed to be loaded through the various IO options availab
 benefit of `TinkerFactory` to help get them bootstrapped. For 3.2.10, Grateful Dead is now more conveniently loaded
 via that same method as the other toy graphs with `TinkerFactory.createGratefulDead()`.
 
+==== Gremlin Javascript Script Submission
+
+Gremlin Javascript can now submit script, with optional bindings, using the Client class:
+[source,javascript]
+----
+const gremlin = require('gremlin');
+const connection = new gremlin.driver.Client('ws://localhost:8182/gremlin', { traversalSource: 'g' });
+
+connection.submit('g.V().tail()')
+    .then(response => {
+        console.log(response.traversers.length);
+        console.log(response.traversers[0]);
+    });
+
+connection.submit('g.V(vid)', {vid: 1})
+    .then(response => {
+        console.log(response.traversers.length);
+        console.log(response.traversers[0]);
+    });
+----
+
+and you can also translate bytecode steps into script
+
+[source,javascript]
+----
+const gremlin = require('gremlin');
+const graph = new gremlin.process.Graph();
+const connection = new gremlin.driver.Client('ws://localhost:8182/gremlin', { traversalSource: 'g' });
+const translator = new gremlin.process.Translator('g');
+
+const g = graph.traversal();
+g.V().tail();
+const script = translator.translate(g.getBytecode());
+
+connection.submit(script)
+    .then(response => {
+        console.log(response.traversers.length);
+        console.log(response.traversers[0]);
+    });
+----
+
 === Upgrading for Providers
 
 ==== Graph Database Providers
diff --git a/gremlin-javascript/glv/TraversalSource.template b/gremlin-javascript/glv/TraversalSource.template
index f3c7795..6965110 100644
--- a/gremlin-javascript/glv/TraversalSource.template
+++ b/gremlin-javascript/glv/TraversalSource.template
@@ -85,11 +85,9 @@ class Traversal {
   _getNext() {
     while (this.traversers && this._traversersIteratorIndex < this.traversers.length) {
       let traverser = this.traversers[this._traversersIteratorIndex];
-      if (traverser.bulk && traverser.bulk > 0) {
+      if (traverser.bulk > 0) {
         traverser.bulk--;
         return { value: traverser.object, done: false };
-      } else if (traverser.bulk === undefined) {
-        return { value: traverser, done: true }
       }
       this._traversersIteratorIndex++;
     }
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
index 91a4dfb..d91ce20 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
@@ -60,9 +60,9 @@ class Client {
     if (typeof message === 'string' || message instanceof String) {
       const args = {
         'gremlin': message,
-        'bindings': bindings,
+        'bindings': bindings, 
         'language': 'gremlin-groovy',
-        'accept': 'application/json',
+        'accept': 'application/vnd.gremlin-v2.0+json',
         'aliases': { 'g': this._options.traversalSource || 'g' }
       };
 
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 83f4baa..6fcb892 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
@@ -23,6 +23,7 @@ const assert = require('assert');
 const Bytecode = require('../../lib/process/bytecode');
 const graphModule = require('../../lib/structure/graph');
 const helper = require('../helper');
+const t = require('../../lib/process/traversal');
 
 let connection;
 
@@ -54,12 +55,25 @@ describe('Client', function () {
         });
     });
     it('should send and parse a script with bindings', function () {
-      return connection.submit('x + x', {x: 3})
+      return connection.submit('x + x', { x: 3 })
         .then(function (response) {
           assert.ok(response);
           assert.ok(response.traversers);
           assert.strictEqual(response.traversers[0], 6);
         });
     });
+    it('should send and parse a script with non-native javascript bindings', function () {
+      /*return connection.submit('card.toString()', { card: t.cardinality.set })
+        .then(function (response) {
+          console.log(response);
+          assert.ok(response);
+          assert.ok(response.traversers);
+        });*/
+      return connection.submit('g.addV().property(card, nm, val)', { card: t.cardinality.set, nm: 'test', val: 12 } )
+        .then(function (response) {
+          assert.ok(response);
+          assert.ok(response.traversers);
+        });
+    });
   });
 });
\ No newline at end of file
diff --git a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml
index f4d508a..ddaaa95 100644
--- a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml
+++ b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml
@@ -42,7 +42,7 @@ serializers:
   - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0] }}
 processors:
   - { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
-  - { className: org.apache.tinkerpop.gremlin.server.op.standard.StandardOpProcessor, config: { maxParameters: 64 }}
+  - { className: org.apache.tinkerpop.gremlin.server.op.standard.StandardOpProcessor, config: {}}
 metrics: {
   slf4jReporter: {enabled: true, interval: 180000}}
 strictTransactionManagement: false


[tinkerpop] 07/12: Changed Client implementation to wrap DriverRemoteConnection

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-1959-tp33
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 20b7687592b62926d4e820734652fb321d3131d9
Author: Matthew Allen <ma...@runbox.com>
AuthorDate: Wed Sep 5 20:50:42 2018 +0100

    Changed Client implementation to wrap DriverRemoteConnection
---
 .../gremlin-javascript/lib/driver/client.js        | 34 ++++++++++++++++++----
 .../lib/driver/driver-remote-connection.js         |  6 ++--
 .../gremlin-javascript/lib/process/traversal.js    |  4 +--
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
index 89d9347..91a4dfb 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
@@ -21,7 +21,7 @@
 const DriverRemoteConnection = require('./driver-remote-connection');
 const Bytecode = require('../process/bytecode');
 
-class Client extends DriverRemoteConnection {
+class Client {
   /**
    * Creates a new instance of DriverRemoteConnection.
    * @param {String} url The resource uri.
@@ -38,10 +38,24 @@ class Client extends DriverRemoteConnection {
    * @constructor
    */
   constructor(url, options) {
-    super(url, options);
+    this._options = options;
+    this._connection = new DriverRemoteConnection(url, options);
   }
 
-  /** override */
+  /**
+   * Opens the underlying connection to the Gremlin Server, if it's not already opened.
+   * @returns {Promise}
+   */
+  open() {
+    return this._connection.open();
+  }
+
+  /**
+   * Send a request to the Gremlin Server, can send a script or bytecode steps.
+   * @param {Bytecode|string} message The bytecode or script to send
+   * @param {Object} bindings The script bindings, if any.
+   * @returns {Promise}
+   */
   submit(message, bindings) {
     if (typeof message === 'string' || message instanceof String) {
       const args = {
@@ -49,16 +63,24 @@ class Client extends DriverRemoteConnection {
         'bindings': bindings,
         'language': 'gremlin-groovy',
         'accept': 'application/json',
-        'aliases': { 'g': this.traversalSource }
+        'aliases': { 'g': this._options.traversalSource || 'g' }
       };
 
-      return super.submit(null, 'eval', args, null, '');
+      return this._connection.submit(null, 'eval', args, null, '');
     }
 
     if (message instanceof Bytecode) {
-      return super.submit(message);
+      return this._connection.submit(message);
     }
   }
+
+  /**
+   * Closes the underlying connection
+   * @returns {Promise}
+   */
+  close() {
+    return this._connection.close();
+  }
   
 }
 
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
index 81d5124..d8bb8dc 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
@@ -133,9 +133,9 @@ class DriverRemoteConnection extends RemoteConnection {
       // if using op eval need to ensure processor stays unset if caller didn't set it.
       'processor': (!processor && op !== 'eval') ? 'traversal' : processor,
       'args': args || {
-          'gremlin': this._writer.adaptObject(bytecode),
-          'aliases': { 'g': this.traversalSource }
-        }
+        'gremlin': this._writer.adaptObject(bytecode),
+        'aliases': { 'g': this.traversalSource }
+      }
     });
   }
 
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
index 5ec2db5..d39ccf0 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js
@@ -85,11 +85,9 @@ class Traversal {
   _getNext() {
     while (this.traversers && this._traversersIteratorIndex < this.traversers.length) {
       let traverser = this.traversers[this._traversersIteratorIndex];
-      if (traverser.bulk && traverser.bulk > 0) {
+      if (traverser.bulk > 0) {
         traverser.bulk--;
         return { value: traverser.object, done: false };
-      } else if (traverser.bulk === undefined) {
-        return { value: traverser, done: true }
       }
       this._traversersIteratorIndex++;
     }