You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ly...@apache.org on 2022/05/20 17:12:23 UTC
[tinkerpop] 01/01: Handling merge conflicts for gremlin-go strategies
This is an automated email from the ASF dual-hosted git repository.
lyndonb pushed a commit to branch 3.6-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 13a1a35be33a5a4e928b78937a5ba4b8df206c55
Merge: 039d409337 c8db98c5f9
Author: Lyndon Bauto <ly...@bitquilltech.com>
AuthorDate: Fri May 20 10:12:05 2022 -0700
Handling merge conflicts for gremlin-go strategies
.../traversal/translator/GolangTranslator.java | 21 +-
.../traversal/translator/GolangTranslatorTest.java | 4 +-
gremlin-go/README.md | 2 +-
gremlin-go/driver/connection_test.go | 76 +++++++
gremlin-go/driver/cucumber/cucumberWorld.go | 35 +++-
gremlin-go/driver/graphBinary.go | 218 +++++++++++++++++----
gremlin-go/driver/graphBinary_test.go | 32 ++-
gremlin-go/driver/serializer.go | 18 +-
gremlin-go/driver/strategies.go | 206 ++++++++++++-------
gremlin-go/driver/strategies_test.go | 39 +++-
gremlin-go/driver/traversal.go | 41 ++++
11 files changed, 553 insertions(+), 139 deletions(-)
diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GolangTranslator.java
index 70107063f5,93c05af325..9c0c6a39a3
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GolangTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GolangTranslator.java
@@@ -256,33 -245,19 +255,40 @@@ public final class GolangTranslator imp
@Override
protected Script produceScript(final TraversalStrategyProxy<?> o) {
if (o.getConfiguration().isEmpty()) {
- return script.append("strategyFactory(\"" + o.getStrategyClass().getSimpleName() + "\", map[string]interface{}{})");
+ return script.append(GO_PACKAGE_NAME + o.getStrategyClass().getSimpleName() + "()");
} else {
- script.append("strategyFactory(\"" + o.getStrategyClass().getSimpleName() + "\", map[string]interface{}{");
+ script.append(GO_PACKAGE_NAME + o.getStrategyClass().getSimpleName() + "(");
+ script.append(GO_PACKAGE_NAME + o.getStrategyClass().getSimpleName() + "Config{");
final Iterator<String> keys = IteratorUtils.stream(o.getConfiguration().getKeys()).
- filter(e -> !e.equals(TraversalStrategy.STRATEGY)).iterator();
+ filter(e -> !e.equals(TraversalStrategy.STRATEGY)).iterator();
while (keys.hasNext()) {
final String k = keys.next();
++<<<<<<< HEAD
+ script.append("\"");
+ script.append(k);
+ script.append("\": ");
+ if (o.getConfiguration().getProperty(k) instanceof List) {
+ List<Object> list =(List<Object>) o.getConfiguration().getProperty(k);
+ Iterator iterator = list.iterator();
+ script.append("[]interface{}{");
+ while(iterator.hasNext()) {
+ convertToScript(iterator.next());
+ if (iterator.hasNext())
+ script.append(", ");
+ }
+ script.append("}");
+ } else {
+ convertToScript(o.getConfiguration().getProperty(k));
+ }
+ if (keys.hasNext())
+ script.append(", ");
++=======
+ script.append(SymbolHelper.toGolang(k));
+ script.append(": ");
+ convertToScript(o.getConfiguration().getProperty(k));
+ script.append(", ");
++>>>>>>> 3.5-dev
}
-
return script.append("})");
}
}
diff --cc gremlin-go/driver/cucumber/cucumberWorld.go
index bfe21e26a0,7b8c569b55..2e70be6c19
--- a/gremlin-go/driver/cucumber/cucumberWorld.go
+++ b/gremlin-go/driver/cucumber/cucumberWorld.go
@@@ -252,27 -213,16 +252,48 @@@ func strategyFactory(strategyName strin
switch strategyName {
case "VertexProgramStrategy":
graphComputer, _ := params["graphComputer"].(string)
- return gremlingo.VertexProgramStrategy(graphComputer, "", "", 0, nil, nil, nil)
+ config := gremlingo.VertexProgramStrategyConfig{
+ GraphComputer: graphComputer,
+ Workers: 0,
+ Persist: "",
+ Result: "",
+ Vertices: nil,
+ Edges: nil,
+ Configuration: nil,
+ }
+ return gremlingo.VertexProgramStrategy(config)
+ case "ProductiveByStrategy":
+ productiveKeys, _ := params["productiveKeys"]
+ productiveKeysInterface := productiveKeys.([]interface{})
+ var productiveKeysStrings = make([]string, len(productiveKeysInterface))
+ for i := range productiveKeysInterface {
+ productiveKeysStrings[i] = productiveKeysInterface[i].(string)
+ }
- return gremlingo.ProductiveByStrategy(productiveKeysStrings)
++ config := gremlingo.ProductiveByStrategyConfig{
++ ProductiveKeys: productiveKeysStrings,
++ }
++ return gremlingo.ProductiveByStrategy(config)
+ case "ReadOnlyStrategy":
+ return gremlingo.ReadOnlyStrategy()
+ case "SubgraphStrategy":
++ edges, _ := params["edges"].(*gremlingo.GraphTraversal)
++ vertices, _ := params["vertices"].(*gremlingo.GraphTraversal)
++ vertexProperties, _ := params["vertexProperties"].(*gremlingo.GraphTraversal)
+ checkAdjacentVertices, _ := params["checkAdjacentVertices"]
- edges, _ := params["edges"]
- vertices, _ := params["vertices"]
- vertexProperties, _ := params["vertexProperties"]
- return gremlingo.SubgraphStrategy(vertices, edges, vertexProperties, checkAdjacentVertices)
++ config := gremlingo.SubgraphStrategyConfig{
++ Edges: edges,
++ Vertices: vertices,
++ VertexProperties: vertexProperties,
++ CheckAdjacentVertices: checkAdjacentVertices,
++ }
++ return gremlingo.SubgraphStrategy(config)
+ case "SeedStrategy":
+ seed, _ := params["seed"]
- return gremlingo.SeedStrategy(int64(seed.(int)))
++ config := gremlingo.SeedStrategyConfig{
++ Seed: int64(seed.(int)),
++ }
++ return gremlingo.SeedStrategy(config)
}
return nil
+
}
diff --cc gremlin-go/driver/graphBinary.go
index f67bfa8e71,dedd19bc3f..4f07a03eb6
--- a/gremlin-go/driver/graphBinary.go
+++ b/gremlin-go/driver/graphBinary.go
@@@ -76,7 -78,8 +78,9 @@@ const
textPType dataType = 0x28
traversalStrategyType dataType = 0x29
bulkSetType dataType = 0x2a
+ mergeType dataType = 0x2e
+ metricsType dataType = 0x2c
+ traversalMetricsType dataType = 0x2d
durationType dataType = 0x81
nullType dataType = 0xFE
)
diff --cc gremlin-go/driver/strategies.go
index ac3ba68cec,b7d25c9f1f..c6b751907b
--- a/gremlin-go/driver/strategies.go
+++ b/gremlin-go/driver/strategies.go
@@@ -53,14 -53,21 +53,20 @@@ func ElementIdStrategy() TraversalStrat
return &traversalStrategy{name: decorationNamespace + "ElementIdStrategy"}
}
- func HaltedTraverserStrategy(haltedTraverserFactoryName string) *traversalStrategy {
- config := make(map[string]interface{})
- if haltedTraverserFactoryName != "" {
- config["haltedTraverserFactory"] = haltedTraverserFactoryName
+ func HaltedTraverserStrategy(config HaltedTraverserStrategyConfig) TraversalStrategy {
+ configMap := make(map[string]interface{})
+ if config.HaltedTraverserFactoryName != "" {
+ configMap["haltedTraverserFactory"] = config.HaltedTraverserFactoryName
}
- return &traversalStrategy{name: decorationNamespace + "HaltedTraverserStrategy", configuration: config}
+ return &traversalStrategy{name: decorationNamespace + "HaltedTraverserStrategy", configuration: configMap}
+ }
+
+ // HaltedTraverserStrategyConfig provides configuration options for HaltedTraverserStrategy.
+ // Zeroed (unset) values are ignored.
+ type HaltedTraverserStrategyConfig struct {
+ HaltedTraverserFactoryName string
}
-
// OptionsStrategy will not alter the Traversal. It is only a holder for configuration options associated with the
// Traversal meant to be accessed by steps or other classes that might have some interaction with it. It is
// essentially a way for users to provide Traversal level configuration options that can be used in various ways
@@@ -70,20 -77,29 +76,29 @@@ func OptionsStrategy(options map[string
}
// PartitionStrategy partitions the Vertices, Edges and Vertex properties of a Graph into String named
- // partitions (i.e. buckets, subgraphs, etc.). It blinds a Traversal from "seeing" specified areas of
+ // partitions (i.e. buckets, subgraphs, etc.). It blinds a Traversal from "seeing" specified areas of
// the graph. The Traversal will ignore all Graph elements not in those "read" partitions.
- func PartitionStrategy(partitionKey, writePartition string, readPartitions []string, includeMetaProperties bool) *traversalStrategy {
- config := map[string]interface{}{"includeMetaProperties": includeMetaProperties}
- if partitionKey != "" {
- config["partitionKey"] = partitionKey
+ func PartitionStrategy(config PartitionStrategyConfig) TraversalStrategy {
+ configMap := map[string]interface{}{"includeMetaProperties": config.IncludeMetaProperties}
+ if config.PartitionKey != "" {
+ configMap["partitionKey"] = config.PartitionKey
}
- if writePartition != "" {
- config["writePartition"] = writePartition
+ if config.WritePartition != "" {
+ configMap["writePartition"] = config.WritePartition
}
- if len(readPartitions) != 0 {
- config["readPartitions"] = readPartitions
+ if len(config.ReadPartitions) != 0 {
+ configMap["readPartitions"] = config.ReadPartitions
}
- return &traversalStrategy{name: decorationNamespace + "PartitionStrategy", configuration: config}
+ return &traversalStrategy{name: decorationNamespace + "PartitionStrategy", configuration: configMap}
+ }
+
+ // PartitionStrategyConfig provides configuration options for PartitionStrategy.
+ // Zeroed (unset) values are ignored except IncludeMetaProperties.
+ type PartitionStrategyConfig struct {
- PartitionKey string
- WritePartition string
- ReadPartitions []string
++ PartitionKey string
++ WritePartition string
++ ReadPartitions []string
+ IncludeMetaProperties bool
}
// SeedStrategy resets the specified Seed value for Seedable steps, which in turn will produce deterministic
@@@ -101,48 -122,63 +121,67 @@@ type SeedStrategyConfig struct
// SubgraphStrategy provides a way to limit the view of a Traversal. By providing Traversal representations that
// represent a form of filtering criterion for Vertices and/or Edges, this strategy will inject that criterion into
// the appropriate places of a Traversal thus restricting what it Traverses and returns.
- func SubgraphStrategy(vertices, edges, vertexProperties interface{}, checkAdjacentVertices interface{}) *traversalStrategy { // all vars can be Traversal or null
- config := make(map[string]interface{})
- if vertices != nil {
- config["vertices"] = vertices
+ func SubgraphStrategy(config SubgraphStrategyConfig) TraversalStrategy {
+ configMap := make(map[string]interface{})
+ if config.Vertices != nil {
+ configMap["vertices"] = config.Vertices
}
- if edges != nil {
- config["edges"] = edges
+ if config.Edges != nil {
+ configMap["edges"] = config.Edges
}
- if vertexProperties != nil {
- config["vertexProperties"] = vertexProperties
+ if config.VertexProperties != nil {
+ configMap["vertexProperties"] = config.VertexProperties
}
- if checkAdjacentVertices != nil {
- config["checkAdjacentVertices"] = checkAdjacentVertices.(bool)
++ if config.CheckAdjacentVertices != nil {
++ configMap["checkAdjacentVertices"] = config.CheckAdjacentVertices.(bool)
+ }
- return &traversalStrategy{name: decorationNamespace + "SubgraphStrategy", configuration: config}
+ return &traversalStrategy{name: decorationNamespace + "SubgraphStrategy", configuration: configMap}
+ }
+
+ // SubgraphStrategyConfig provides configuration options for SubgraphStrategy. Zeroed (unset) values are ignored.
+ type SubgraphStrategyConfig struct {
- Vertices *GraphTraversal
- Edges *GraphTraversal
- VertexProperties *GraphTraversal
++ Vertices *GraphTraversal
++ Edges *GraphTraversal
++ VertexProperties *GraphTraversal
++ CheckAdjacentVertices interface{}
}
- func VertexProgramStrategy(graphComputer, persist, result string, workers int,
- vertices, edges interface{}, configuration map[string]interface{}) *traversalStrategy {
- config := make(map[string]interface{})
- if graphComputer != "" {
- config["graphComputer"] = graphComputer
+ func VertexProgramStrategy(config VertexProgramStrategyConfig) TraversalStrategy {
+ configMap := make(map[string]interface{})
+ if config.GraphComputer != "" {
+ configMap["graphComputer"] = config.GraphComputer
}
- if persist != "" {
- config["persist"] = persist
+ if config.Workers != 0 {
+ configMap["workers"] = config.Workers
}
- if result != "" {
- config["result"] = result
+ if config.Persist != "" {
+ configMap["persist"] = config.Persist
}
- if workers != 0 {
- config["workers"] = workers
+ if config.Result != "" {
+ configMap["result"] = config.Result
}
- if vertices != nil {
- config["vertices"] = vertices
+ if config.Vertices != nil {
+ configMap["vertices"] = config.Vertices
}
- if edges != nil {
- config["edges"] = edges
+ if config.Edges != nil {
+ configMap["edges"] = config.Edges
}
- for k, v := range configuration {
- config[k] = v
+ for k, v := range config.Configuration {
+ configMap[k] = v
}
- return &traversalStrategy{name: computerDecorationNamespace + "VertexProgramStrategy", configuration: config}
+ return &traversalStrategy{name: computerDecorationNamespace + "VertexProgramStrategy", configuration: configMap}
+ }
+
+ // VertexProgramStrategyConfig provides configuration options for VertexProgramStrategy.
+ // Zeroed (unset) values are ignored.
+ type VertexProgramStrategyConfig struct {
+ GraphComputer string
- Workers int
- Persist string
- Result string
- Vertices *GraphTraversal
- Edges *GraphTraversal
++ Workers int
++ Persist string
++ Result string
++ Vertices *GraphTraversal
++ Edges *GraphTraversal
+ Configuration map[string]interface{}
}
// Finalization strategies
@@@ -160,13 -202,20 +205,20 @@@ type MatchAlgorithmStrategyConfig struc
// EdgeLabelVerificationStrategy does not allow Edge traversal steps to have no label specified.
// Providing one or more labels is considered to be a best practice, however, TinkerPop will not force
// the specification of Edge labels; instead, providers or users will have to enable this strategy explicitly.
- func EdgeLabelVerificationStrategy(logWarning, throwException bool) *traversalStrategy {
- config := map[string]interface{}{
- "logWarning": logWarning,
- "throwException": throwException,
+ func EdgeLabelVerificationStrategy(config EdgeLabelVerificationStrategyConfig) TraversalStrategy {
+ configMap := map[string]interface{}{
+ "logWarning": config.LogWarning,
+ "throwException": config.ThrowExcecption,
}
- return &traversalStrategy{name: verificationNamespace + "EdgeLabelVerificationStrategy", configuration: config}
+ return &traversalStrategy{name: verificationNamespace + "EdgeLabelVerificationStrategy", configuration: configMap}
+ }
+
+ // EdgeLabelVerificationStrategyConfig provides configuration options for EdgeLabelVerificationStrategy.
+ // Zeroed (unset) values are used.
+ type EdgeLabelVerificationStrategyConfig struct {
- LogWarning bool
++ LogWarning bool
+ ThrowExcecption bool
}
// LambdaRestrictionStrategy does not allow lambdas to be used in a Traversal. The contents of a lambda
@@@ -184,15 -233,23 +236,23 @@@ func ReadOnlyStrategy() TraversalStrate
// ReservedKeysVerificationStrategy detects property keys that should not be used by the traversal.
// A term may be reserved by a particular graph implementation or as a convention given best practices.
- func ReservedKeysVerificationStrategy(logWarning, throwException bool, keys []string) *traversalStrategy {
- config := map[string]interface{}{
- "logWarning": logWarning,
- "throwException": throwException,
+ func ReservedKeysVerificationStrategy(config ReservedKeysVerificationStrategyConfig) TraversalStrategy {
+ configMap := map[string]interface{}{
+ "logWarning": config.LogWarning,
+ "throwException": config.ThrowException,
}
- if keys != nil {
- config["keys"] = keys
+ if len(config.Keys) != 0 {
+ configMap["keys"] = config.Keys
}
- return &traversalStrategy{name: verificationNamespace + "ReservedKeysVerificationStrategy", configuration: config}
+ return &traversalStrategy{name: verificationNamespace + "ReservedKeysVerificationStrategy", configuration: configMap}
+ }
+
+ // ReservedKeysVerificationStrategyConfig provides configuration options for ReservedKeysVerificationStrategy.
+ // Zeroed (unset) values are used except Keys.
+ type ReservedKeysVerificationStrategyConfig struct {
- LogWarning bool
++ LogWarning bool
+ ThrowException bool
- Keys []string
++ Keys []string
}
// Optimization strategies
diff --cc gremlin-go/driver/strategies_test.go
index 763d46a16b,f8a3d37f41..9052ac6cd2
--- a/gremlin-go/driver/strategies_test.go
+++ b/gremlin-go/driver/strategies_test.go
@@@ -97,8 -104,13 +104,13 @@@ func TestStrategy(t *testing.T)
t.Run("Test read with SubgraphStrategy", func(t *testing.T) {
g := getModernGraph(t, testNoAuthUrl, &AuthInfo{}, &tls.Config{})
defer g.remoteConnection.Close()
--
- count, err := g.WithStrategies(SubgraphStrategy(T__.HasLabel(testLabel), nil, nil, nil)).V().Count().ToList()
+ config := SubgraphStrategyConfig{
- Vertices: T__.HasLabel(testLabel),
- Edges: nil,
- VertexProperties: nil,
++ Vertices: T__.HasLabel(testLabel),
++ Edges: nil,
++ VertexProperties: nil,
++ CheckAdjacentVertices: nil,
+ }
+ count, err := g.WithStrategies(SubgraphStrategy(config)).V().Count().ToList()
assert.Nil(t, err)
assert.NotNil(t, count)
assert.Equal(t, 1, len(count))