You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by fl...@apache.org on 2018/07/31 20:19:34 UTC
[05/45] tinkerpop git commit: TINKERPOP-1996 Introduce read() and
write() steps
TINKERPOP-1996 Introduce read() and write() steps
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/ec1d05f7
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/ec1d05f7
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/ec1d05f7
Branch: refs/heads/TINKERPOP-1774
Commit: ec1d05f74fa875e4a07699dc89c3d1956aab586f
Parents: ce73ceb
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 29 15:04:17 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jul 19 13:39:29 2018 -0400
----------------------------------------------------------------------
.../traversal/dsl/graph/GraphTraversal.java | 2 +
.../dsl/graph/GraphTraversalSource.java | 17 +++
.../process/traversal/step/map/ReadStep.java | 112 +++++++++++++++++++
.../process/traversal/step/map/WriteStep.java | 111 ++++++++++++++++++
.../strategy/verification/IoUsageStrategy.java | 60 ++++++++++
.../verification/IoUsageStrategyTest.java | 93 +++++++++++++++
.../glv/GraphTraversalSource.template | 4 +-
gremlin-dotnet/glv/generate.groovy | 5 +-
.../Process/Traversal/GraphTraversalSource.cs | 22 ++++
.../lib/process/graph-traversal.js | 20 ++++
.../gremlin_python/process/graph_traversal.py | 10 ++
11 files changed, 452 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index 63aa65d..210367f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -2817,6 +2817,8 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
public static final String skip = "skip";
public static final String tail = "tail";
public static final String coin = "coin";
+ public static final String read = "read";
+ public static final String write = "write";
public static final String timeLimit = "timeLimit";
public static final String simplePath = "simplePath";
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
index bc3ef9e..9b82108 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
@@ -31,6 +31,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStartStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ReadStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.WriteStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.RequirementsStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
@@ -40,6 +42,7 @@ import org.apache.tinkerpop.gremlin.structure.Transaction;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import java.util.Map;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
@@ -390,6 +393,20 @@ public class GraphTraversalSource implements TraversalSource {
return traversal.addStep(new GraphStep<>(traversal, Edge.class, true, edgesIds));
}
+ public GraphTraversal<Map<String,Object>, Map<String,Object>> read(final String localFile) {
+ final GraphTraversalSource clone = this.clone();
+ clone.bytecode.addStep(GraphTraversal.Symbols.read, localFile);
+ final GraphTraversal.Admin<Map<String,Object>, Map<String,Object>> traversal = new DefaultGraphTraversal<>(clone);
+ return traversal.addStep(new ReadStep(traversal, localFile));
+ }
+
+ public GraphTraversal<Map<String,Object>, Map<String,Object>> write(final String localFile) {
+ final GraphTraversalSource clone = this.clone();
+ clone.bytecode.addStep(GraphTraversal.Symbols.write, localFile);
+ final GraphTraversal.Admin<Map<String,Object>, Map<String,Object>> traversal = new DefaultGraphTraversal<>(clone);
+ return traversal.addStep(new WriteStep(traversal, localFile));
+ }
+
/**
* Proxies calls through to the underlying {@link Graph#tx()}.
*/
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadStep.java
new file mode 100644
index 0000000..afc3e53
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReadStep.java
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.TraverserGenerator;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Configuring;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
+import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoReader;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Reads data from a file into a {@link Graph}. This step is meant to be used as the first and last step in a
+ * traversal.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class ReadStep extends AbstractStep<Map<String,Object>, Map<String,Object>> implements Configuring {
+
+ private Parameters parameters = new Parameters();
+ private boolean first = true;
+ private String localFile;
+
+ public ReadStep(final Traversal.Admin traversal, final String localFile) {
+ super(traversal);
+
+ if (null == localFile || localFile.isEmpty())
+ throw new IllegalArgumentException("localFile cannot be null or empty");
+ if (!new File(localFile).exists()) throw new IllegalStateException(localFile + " does not exist");
+
+ this.localFile = localFile;
+ }
+
+ @Override
+ public Parameters getParameters() {
+ return this.parameters;
+ }
+
+ @Override
+ public void configure(final Object... keyValues) {
+ this.parameters.set(null, keyValues);
+ }
+
+ @Override
+ protected Traverser.Admin<Map<String,Object>> processNextStart() {
+ if (!this.first) throw FastNoSuchElementException.instance();
+
+ this.first = false;
+ final TraverserGenerator generator = this.getTraversal().getTraverserGenerator();
+ final File file = new File(localFile);
+
+ try (final InputStream stream = new FileInputStream(file)) {
+ final Graph graph = (Graph) this.traversal.getGraph().get();
+ GryoReader.build().create().readGraph(stream, graph);
+
+ final Map<String,Object> stats = new LinkedHashMap<>();
+ stats.put("vertices", IteratorUtils.count(graph.vertices()));
+ stats.put("edges", IteratorUtils.count(graph.edges()));
+
+ return generator.generate(stats, this, 1L);
+ } catch (IOException ioe) {
+ throw new IllegalStateException(String.format("Could not read file %s into graph", localFile), ioe);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int hash = super.hashCode() ^ this.parameters.hashCode();
+ return (null != this.localFile) ? (hash ^ localFile.hashCode()) : hash;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, localFile, this.parameters);
+ }
+
+ @Override
+ public ReadStep clone() {
+ final ReadStep clone = (ReadStep) super.clone();
+ clone.parameters = this.parameters.clone();
+ clone.localFile = this.localFile;
+ return clone;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/WriteStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/WriteStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/WriteStep.java
new file mode 100644
index 0000000..e9346cf
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/WriteStep.java
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.TraverserGenerator;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Configuring;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
+import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoWriter;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Writes data to a file from a {@link Graph}. This step is meant to be used as the first and last step in a
+ * traversal.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class WriteStep extends AbstractStep<Map<String,Object>, Map<String,Object>> implements Configuring {
+
+ private Parameters parameters = new Parameters();
+ private boolean first = true;
+ private String localFile;
+
+ public WriteStep(final Traversal.Admin traversal, final String localFile) {
+ super(traversal);
+
+ if (null == localFile || localFile.isEmpty())
+ throw new IllegalArgumentException("localFile cannot be null or empty");
+
+ this.localFile = localFile;
+ }
+
+ @Override
+ public Parameters getParameters() {
+ return this.parameters;
+ }
+
+ @Override
+ public void configure(final Object... keyValues) {
+ this.parameters.set(null, keyValues);
+ }
+
+ @Override
+ protected Traverser.Admin<Map<String,Object>> processNextStart() {
+ if (!this.first) throw FastNoSuchElementException.instance();
+
+ this.first = false;
+ final TraverserGenerator generator = this.getTraversal().getTraverserGenerator();
+
+ final File file = new File(localFile);
+ try (final OutputStream stream = new FileOutputStream(file)) {
+ final Graph graph = (Graph) this.traversal.getGraph().get();
+ GryoWriter.build().create().writeGraph(stream, graph);
+
+ final Map<String, Object> stats = new LinkedHashMap<>();
+ stats.put("vertices", IteratorUtils.count(graph.vertices()));
+ stats.put("edges", IteratorUtils.count(graph.edges()));
+
+ return generator.generate(stats, this, 1L);
+ } catch (IOException ioe) {
+ throw new IllegalStateException(String.format("Could not write file %s from graph", localFile), ioe);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int hash = super.hashCode() ^ this.parameters.hashCode();
+ return (null != this.localFile) ? (hash ^ localFile.hashCode()) : hash;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, localFile, this.parameters);
+ }
+
+ @Override
+ public WriteStep clone() {
+ final WriteStep clone = (WriteStep) super.clone();
+ clone.parameters = this.parameters.clone();
+ clone.localFile = this.localFile;
+ return clone;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/IoUsageStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/IoUsageStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/IoUsageStrategy.java
new file mode 100644
index 0000000..95761ff
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/IoUsageStrategy.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.strategy.verification;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ReadStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.WriteStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+
+/**
+ * {@code IoUsageStrategy} prevents the {@link GraphTraversalSource#read(String)} and
+ * {@link GraphTraversalSource#write(String)} steps from being used outside of their intended scope, which is as the
+ * first and last step in a traversal. Therefore, it can only be used as {@code g.read('file.gryo')} and
+ * {@code g.write('file.gryo')}. As both of these steps take additional configuration, the use of the
+ * {@link GraphTraversal#with(String, Object)} is acceptable.
+ * <p/>
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @example <pre>
+ * g.read('file.kryo').V() // throws VerificationException
+ * g.write('file.kryo').V() // throws VerificationException
+ * </pre>
+ */
+public final class IoUsageStrategy extends AbstractTraversalStrategy<TraversalStrategy.VerificationStrategy> implements TraversalStrategy.VerificationStrategy {
+
+ private static final IoUsageStrategy INSTANCE = new IoUsageStrategy();
+
+ private IoUsageStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal) {
+ if ((traversal.getStartStep() instanceof ReadStep || traversal.getStartStep() instanceof WriteStep) && traversal.getSteps().size() > 1) {
+ throw new VerificationException("The read() or write() steps must be the first and only step in the traversal - they cannot be used with other steps", traversal);
+ }
+ }
+
+ public static IoUsageStrategy instance() {
+ return INSTANCE;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/IoUsageStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/IoUsageStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/IoUsageStrategyTest.java
new file mode 100644
index 0000000..907e2b7
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/IoUsageStrategyTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.strategy.verification;
+
+import org.apache.tinkerpop.gremlin.TestHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class IoUsageStrategyTest {
+
+ private static final GraphTraversalSource g = EmptyGraph.instance().traversal();
+
+ private static File junkFile;
+
+ static {
+ try {
+ junkFile = TestHelper.generateTempFile(IoUsageStrategyTest.class, "fake", "kryo");
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {"g.read('a.kryo')", g.read(junkFile.getAbsolutePath()), true},
+ {"g.write('a.kryo')", g.write(junkFile.getAbsolutePath()), true},
+ {"g.read('a.kryo').with(\"x\", \"y\")", g.read(junkFile.getAbsolutePath()).with("x", "y"), true},
+ {"g.write('a.kryo').with(\"x\", \"y\")", g.write(junkFile.getAbsolutePath()).with("x", "y"), true},
+ {"g.read('a.kryo').V()", g.read(junkFile.getAbsolutePath()).V(), false},
+ {"g.write('a.kryo').V()", g.write(junkFile.getAbsolutePath()).V(), false}
+ });
+ }
+
+ @Parameterized.Parameter(value = 0)
+ public String name;
+
+ @Parameterized.Parameter(value = 1)
+ public Traversal traversal;
+
+ @Parameterized.Parameter(value = 2)
+ public boolean allow;
+
+ @Test
+ public void shouldBeVerified() {
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(IoUsageStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ if (allow) {
+ traversal.asAdmin().applyStrategies();
+ } else {
+ try {
+ traversal.asAdmin().applyStrategies();
+ fail("The strategy should not allow read()/write() to be used with other steps: " + this.traversal);
+ } catch (VerificationException ise) {
+ assertTrue(ise.getMessage().contains("read() or write() steps"));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-dotnet/glv/GraphTraversalSource.template
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/glv/GraphTraversalSource.template b/gremlin-dotnet/glv/GraphTraversalSource.template
index afa4297..23d66e5 100644
--- a/gremlin-dotnet/glv/GraphTraversalSource.template
+++ b/gremlin-dotnet/glv/GraphTraversalSource.template
@@ -127,9 +127,9 @@ namespace Gremlin.Net.Process.Traversal
/// Spawns a <see cref="GraphTraversal{SType, EType}" /> off this graph traversal source and adds the <%= method.methodName %> step to that
/// traversal.
/// </summary>
- public GraphTraversal<$method.typeNameString> <%= toCSharpMethodName.call(method.methodName) %><%= method.tParam %>(<%= method.parameters %>)
+ public GraphTraversal<$method.t1, $method.t2> <%= toCSharpMethodName.call(method.methodName) %><%= method.tParam %>(<%= method.parameters %>)
{
- var traversal = new GraphTraversal<$method.typeNameString>(TraversalStrategies, new Bytecode(Bytecode));
+ var traversal = new GraphTraversal<$method.t1, $method.t2>(TraversalStrategies, new Bytecode(Bytecode));
<% if (method.parameters.contains("params ")) {
%>var args = new List<$method.argsListType>(<%= method.paramNames.init().size() %> + <%= method.paramNames.last() %>.Length) {<%= method.paramNames.init().join(", ") %>};
args.AddRange(<%= method.paramNames.last() %>);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-dotnet/glv/generate.groovy
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/glv/generate.groovy b/gremlin-dotnet/glv/generate.groovy
index e542471..bd2d9d7 100644
--- a/gremlin-dotnet/glv/generate.groovy
+++ b/gremlin-dotnet/glv/generate.groovy
@@ -38,6 +38,7 @@ def toCSharpTypeMap = ["Long": "long",
"Object[]": "object[]",
"Class": "Type",
"Class[]": "Type[]",
+ "java.util.Map<java.lang.String, java.lang.Object>": "IDictionary<string, object>",
"java.util.Map<java.lang.String, E2>": "IDictionary<string, E2>",
"java.util.Map<java.lang.String, B>": "IDictionary<string, E2>",
"java.util.Map<java.lang.Object, E2>": "IDictionary<object, E2>",
@@ -251,13 +252,13 @@ def binding = ["pmethods": P.class.getMethods().
unique { a,b -> a.name <=> b.name ?: getCSharpParamTypeString(a) <=> getCSharpParamTypeString(b) }.
collect { javaMethod ->
def typeNames = getJavaGenericTypeParameterTypeNames(javaMethod)
- def typeNameString = typeNames.join(", ")
+ def t1 = toCSharpType(typeNames[0])
def t2 = toCSharpType(typeNames[1])
def tParam = getCSharpGenericTypeParam(t2)
def parameters = getCSharpParamString(javaMethod, true)
def paramNames = getParamNames(javaMethod.parameters)
def argsListType = getArgsListType(parameters)
- return ["methodName": javaMethod.name, "typeNameString": typeNameString, "tParam":tParam, "parameters":parameters, "paramNames":paramNames, "argsListType":argsListType]
+ return ["methodName": javaMethod.name, "t1":t1, "t2":t2, "tParam":tParam, "parameters":parameters, "paramNames":paramNames, "argsListType":argsListType]
},
"graphStepMethods": GraphTraversal.getMethods().
findAll { GraphTraversal.class.equals(it.returnType) }.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
index 2816c05..630ac28 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
@@ -333,6 +333,28 @@ namespace Gremlin.Net.Process.Traversal
return traversal;
}
+ /// <summary>
+ /// Spawns a <see cref="GraphTraversal{SType, EType}" /> off this graph traversal source and adds the read step to that
+ /// traversal.
+ /// </summary>
+ public GraphTraversal<IDictionary<string, object>, IDictionary<string, object>> Read(string localFile)
+ {
+ var traversal = new GraphTraversal<IDictionary<string, object>, IDictionary<string, object>>(TraversalStrategies, new Bytecode(Bytecode));
+ traversal.Bytecode.AddStep("read", localFile);
+ return traversal;
+ }
+
+ /// <summary>
+ /// Spawns a <see cref="GraphTraversal{SType, EType}" /> off this graph traversal source and adds the write step to that
+ /// traversal.
+ /// </summary>
+ public GraphTraversal<IDictionary<string, object>, IDictionary<string, object>> Write(string localFile)
+ {
+ var traversal = new GraphTraversal<IDictionary<string, object>, IDictionary<string, object>>(TraversalStrategies, new Bytecode(Bytecode));
+ traversal.Bytecode.AddStep("write", localFile);
+ return traversal;
+ }
+
}
#pragma warning restore 1591
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
----------------------------------------------------------------------
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 f143542..8fa51de 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,26 @@ class GraphTraversalSource {
return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b);
}
+ /**
+ * read GraphTraversalSource step method.
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+ read(...args) {
+ const b = new Bytecode(this.bytecode).addStep('read', args);
+ return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ }
+
+ /**
+ * write GraphTraversalSource step method.
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+ write(...args) {
+ const b = new Bytecode(this.bytecode).addStep('write', args);
+ return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ }
+
}
/**
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ec1d05f7/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
index bb81d87..e559613 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
@@ -106,6 +106,16 @@ class GraphTraversalSource(object):
traversal.bytecode.add_step("inject", *args)
return traversal
+ def read(self, *args):
+ traversal = self.get_graph_traversal()
+ traversal.bytecode.add_step("read", *args)
+ return traversal
+
+ def write(self, *args):
+ traversal = self.get_graph_traversal()
+ traversal.bytecode.add_step("write", *args)
+ return traversal
+
class GraphTraversal(Traversal):
def __init__(self, graph, traversal_strategies, bytecode):