{"action":"created","issue":{"url":"https://api.github.com/repos/apache/tinkerpop/issues/922","repository_url":"https://api.github.com/repos/apache/tinkerpop","labels_url":"https://api.github.com/repos/apache/tinkerpop/issues/922/labels{/name}","comments_url":"https://api.github.com/repos/apache/tinkerpop/issues/922/comments","events_url":"https://api.github.com/repos/apache/tinkerpop/issues/922/events","html_url":"https://github.com/apache/tinkerpop/pull/922","id":353963154,"node_id":"MDExOlB1bGxSZXF1ZXN0MjEwODczNzU1","number":922,"title":"TINKERPOP-1959: Gremlin Javascript ability to send a script to the Gremlin Server.","user":{"login":"mattallenuk","id":4797711,"node_id":"MDQ6VXNlcjQ3OTc3MTE=","avatar_url":"https://avatars1.githubusercontent.com/u/4797711?v=4","gravatar_id":"","url":"https://api.github.com/users/mattallenuk","html_url":"https://github.com/mattallenuk","followers_url":"https://api.github.com/users/mattallenuk/followers","following_url":"https://api.github.com/users/mattallenuk/following{/other_user}","gists_url":"https://api.github.com/users/mattallenuk/gists{/gist_id}","starred_url":"https://api.github.com/users/mattallenuk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mattallenuk/subscriptions","organizations_url":"https://api.github.com/users/mattallenuk/orgs","repos_url":"https://api.github.com/users/mattallenuk/repos","events_url":"https://api.github.com/users/mattallenuk/events{/privacy}","received_events_url":"https://api.github.com/users/mattallenuk/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":13,"created_at":"2018-08-25T00:08:44Z","updated_at":"2018-10-04T19:42:04Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/apache/tinkerpop/pulls/922","html_url":"https://github.com/apache/tinkerpop/pull/922","diff_url":"https://github.com/apache/tinkerpop/pull/922.diff","patch_url":"https://github.com/apache/tinkerpop/pull/922.patch"},"body":"Hiya,\r\n\r\nSubmitting a PR for consideration re sending a script to a Gremlin server. \r\n\r\nI've added an eval() function to GraphTraversal and TraveralSource classes. This function takes an optional script string and bindings map. If a script is provided it will be sent directly to the server, discarding any previous glv steps, if no script is provided one will be built from the previously set glv steps.\r\n\r\nRemoteStrategy class has been changed to handle submission of eval operations to the DriverRemoteConnection.\r\n\r\nBytecode class has had a toScript() function added that takes the glv instructions and produces a script with bindings.\r\n\r\nTraversal class has been changed to handle responses from eval op execution.\r\n\r\nI wanted to have the option to build from glv instructions as I'll be using the library to access an Azure CosmoDB which currently doesn't support bytecode but when it does it will make it much easier to update projects to using bytecode by removing the eval function and replacing with one of the other terminal actions.\r\n\r\nI do have a couple of queries regarding the proposed changes:\r\n\r\n1) Is it safe to assume that a returned value not containing a bulk property was executed by an eval op?\r\nWhen parsing the returned data from the server in the TraversalSource class it appears that any data returned from a bytecode op contains a bulk property. Can it be assumed then that any return value that doesn't contain a bulk property is a valid return value for eval op, or should there be some sort of checking in place?\r\n\r\n```\r\n_getNext() {\r\n    while (this.traversers && this._traversersIteratorIndex < this.traversers.length) {\r\n      let traverser = this.traversers[this._traversersIteratorIndex];\r\n      if (traverser.bulk && traverser.bulk > 0) {\r\n        traverser.bulk--;\r\n        return { value: traverser.object, done: false };\r\n      } else if (traverser.bulk === undefined) {\r\n        return { value: traverser, done: true }\r\n      }\r\n      this._traversersIteratorIndex++;\r\n    }\r\n```\r\n\r\n2) Should every parameter be bound when building a dynamic script?\r\nThe Bytecode::toScript() function converts any glv parameters into bindings to be sent to the server. Should this make consideration for parameters that are likely not set by users. For example g.addV('flowers', 'Lilac'), can it be assumed that flowers was set by the implementer and Lilac by a user? If so should the function be changed to only bind parameters we can assume are set by users?\r\n\r\n3) Does the unit test need to be more thorough and check more varied instructions and more complex glv queries/instructions?\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/apache/tinkerpop/issues/comments/427144864","html_url":"https://github.com/apache/tinkerpop/pull/922#issuecomment-427144864","issue_url":"https://api.github.com/repos/apache/tinkerpop/issues/922","id":427144864,"node_id":"MDEyOklzc3VlQ29tbWVudDQyNzE0NDg2NA==","user":{"login":"spmallette","id":384249,"node_id":"MDQ6VXNlcjM4NDI0OQ==","avatar_url":"https://avatars0.githubusercontent.com/u/384249?v=4","gravatar_id":"","url":"https://api.github.com/users/spmallette","html_url":"https://github.com/spmallette","followers_url":"https://api.github.com/users/spmallette/followers","following_url":"https://api.github.com/users/spmallette/following{/other_user}","gists_url":"https://api.github.com/users/spmallette/gists{/gist_id}","starred_url":"https://api.github.com/users/spmallette/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spmallette/subscriptions","organizations_url":"https://api.github.com/users/spmallette/orgs","repos_url":"https://api.github.com/users/spmallette/repos","events_url":"https://api.github.com/users/spmallette/events{/privacy}","received_events_url":"https://api.github.com/users/spmallette/received_events","type":"User","site_admin":false},"created_at":"2018-10-04T19:42:04Z","updated_at":"2018-10-04T19:42:04Z","author_association":"CONTRIBUTOR","body":"It works with Java and GraphSON 2.0:\r\n\r\n```text\r\ngremlin> cluster = Cluster.build().serializer(\"GRAPHSON_V2D0\").create()\r\n==>localhost/127.0.0.1:8182\r\ngremlin> client = cluster.connect()\r\n==>org.apache.tinkerpop.gremlin.driver.Client$ClusteredClient@24a298a6\r\ngremlin> client.submit(\"g.addV().property(c,k,v)\", [c:set,k:'name',v:123]).all().get()\r\n==>result{object=v[4] class=org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex}\r\ngremlin> client.submit(\"g.V().has('name',123).count()\").all().get()\r\n==>result{object=1 class=java.lang.Long}\r\n```\r\n\r\nSo, i'm not sure what's wrong. If you want to commit/push what you have i can try to test on my own to see what I (or maybe someone else) can figure out.\r\n\r\n"}}
{"actor":{"display_login":"spmallette"}}