Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
* Fixed a bug in Gremlin Console which prevented handling of `gremlin.sh` flags that had an "=" between the flag and its arguments.
* Fixed bug where `SparkMessenger` was not applying the `edgeFunction` from `MessageScope`.
* Fixed a bug in `ComputerAwareStep` that didn't handle `reset()` properly and thus occasionally produced some extra traversers.
* Removed `TraversalPredicate` class in Gremlin.Net. It is now included in the `P` class instead.

[[release-3-2-7]]
=== TinkerPop 3.2.7 (Release Date: December 17, 2017)
Expand Down
12 changes: 12 additions & 0 deletions docs/src/upgrade/release-3.2.x-incubating.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ However, usage of these tokens themselves shouldn't change at all (e.g. `T.Id` i

See: link:https://issues.apache.org/jira/browse/TINKERPOP-1901[TINKERPOP-1901]

==== Gremlin.Net: Traversal Predicate Classes Merged

Gremlin.Net used two classes for traversal predicates: `P` and `TraversalPredicate`. Steps that worked with traversal
predicates expected objects of type `TraversalPredicate`, but they were constructed from the `P` class
(e.g. `P.Gt(1)` returned a `TraversalPredicate`). Merging these two classes into the `P` class should avoid unnecessary
confusion. Most users should not notice this change as predicates can still be constructed exactly as before, e.g.,
`P.Gt(1).And(P.Lt(3))` still works without any modifications.
Only users that implemented their own predicates and used `TraversalPredicate` as the base class need to change their
implementation to now use `P` as the new base class.

See: link:https://issues.apache.org/jira/browse/TINKERPOP-1919[TINKERPOP-1919]

=== Upgrading for Providers

==== Graph System Providers
Expand Down
62 changes: 57 additions & 5 deletions gremlin-dotnet/glv/P.template
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,72 @@ namespace Gremlin.Net.Process.Traversal
/// A <see cref="P" /> is a predicate of the form Func&lt;object, bool&gt;.
/// That is, given some object, return true or false.
/// </summary>
public class P
public class P : IPredicate
{
/// <summary>
/// Initializes a new instance of the <see cref="P" /> class.
/// </summary>
/// <param name="operatorName">The name of the predicate.</param>
/// <param name="value">The value of the predicate.</param>
/// <param name="other">An optional other predicate that is used as an argument for this predicate.</param>
public P(string operatorName, dynamic value, P other = null)
{
OperatorName = operatorName;
Value = value;
Other = other;
}

/// <summary>
/// Gets the name of the predicate.
/// </summary>
public string OperatorName { get; }

/// <summary>
/// Gets the value of the predicate.
/// </summary>
public dynamic Value { get; }

/// <summary>
/// Gets an optional other predicate that is used as an argument for this predicate.
/// </summary>
public P Other { get; }

/// <summary>
/// Returns a composed predicate that represents a logical AND of this predicate and another.
/// </summary>
/// <param name="otherPredicate">A predicate that will be logically-ANDed with this predicate.</param>
/// <returns>The composed predicate.</returns>
public P And(P otherPredicate)
{
return new P("and", this, otherPredicate);
}

/// <summary>
/// Returns a composed predicate that represents a logical OR of this predicate and another.
/// </summary>
/// <param name="otherPredicate">A predicate that will be logically-ORed with this predicate.</param>
/// <returns>The composed predicate.</returns>
public P Or(P otherPredicate)
{
return new P("or", this, otherPredicate);
}
<% pmethods.findAll{ !(it in ["within", "without"]) }.each { method -> %>
public static TraversalPredicate <%= toCSharpMethodName.call(method) %>(params object[] args)
public static P <%= toCSharpMethodName.call(method) %>(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("<%= method %>", value);
return new P("<%= method %>", value);
}
<% } %><% pmethods.findAll{ it in ["within", "without"] }.each { method -> %>
public static TraversalPredicate <%= toCSharpMethodName.call(method) %>(params object[] args)
public static P <%= toCSharpMethodName.call(method) %>(params object[] args)
{
return new TraversalPredicate("<%= method %>", args);
return new P("<%= method %>", args);
}
<% } %>
/// <inheritdoc />
public override string ToString()
{
return Other == null ? \$"{OperatorName}({Value})" : \$"{OperatorName}({Value},{Other})";
}
}

#pragma warning restore 1591
Expand Down
2 changes: 1 addition & 1 deletion gremlin-dotnet/glv/generate.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def toCSharpTypeMap = ["Long": "long",
"Traversal": "ITraversal",
"Traversal[]": "ITraversal[]",
"Predicate": "IPredicate",
"P": "TraversalPredicate",
"P": "P",
"TraversalStrategy": "ITraversalStrategy",
"TraversalStrategy[]": "ITraversalStrategy[]",
"Function": "IFunction",
Expand Down
20 changes: 10 additions & 10 deletions gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ public GraphTraversal<S, E> Has (string propertyKey, object value)
/// <summary>
/// Adds the has step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> Has (string propertyKey, TraversalPredicate predicate)
public GraphTraversal<S, E> Has (string propertyKey, P predicate)
{
Bytecode.AddStep("has", propertyKey, predicate);
return Wrap<S, E>(this);
Expand All @@ -685,7 +685,7 @@ public GraphTraversal<S, E> Has (string label, string propertyKey, object value)
/// <summary>
/// Adds the has step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> Has (string label, string propertyKey, TraversalPredicate predicate)
public GraphTraversal<S, E> Has (string label, string propertyKey, P predicate)
{
Bytecode.AddStep("has", label, propertyKey, predicate);
return Wrap<S, E>(this);
Expand All @@ -712,7 +712,7 @@ public GraphTraversal<S, E> Has (T accessor, object value)
/// <summary>
/// Adds the has step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> Has (T accessor, TraversalPredicate predicate)
public GraphTraversal<S, E> Has (T accessor, P predicate)
{
Bytecode.AddStep("has", accessor, predicate);
return Wrap<S, E>(this);
Expand Down Expand Up @@ -741,7 +741,7 @@ public GraphTraversal<S, E> HasId (object id, params object[] otherIds)
/// <summary>
/// Adds the hasId step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> HasId (TraversalPredicate predicate)
public GraphTraversal<S, E> HasId (P predicate)
{
Bytecode.AddStep("hasId", predicate);
return Wrap<S, E>(this);
Expand All @@ -750,7 +750,7 @@ public GraphTraversal<S, E> HasId (TraversalPredicate predicate)
/// <summary>
/// Adds the hasKey step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> HasKey (TraversalPredicate predicate)
public GraphTraversal<S, E> HasKey (P predicate)
{
Bytecode.AddStep("hasKey", predicate);
return Wrap<S, E>(this);
Expand All @@ -770,7 +770,7 @@ public GraphTraversal<S, E> HasKey (string label, params string[] otherLabels)
/// <summary>
/// Adds the hasLabel step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> HasLabel (TraversalPredicate predicate)
public GraphTraversal<S, E> HasLabel (P predicate)
{
Bytecode.AddStep("hasLabel", predicate);
return Wrap<S, E>(this);
Expand Down Expand Up @@ -810,7 +810,7 @@ public GraphTraversal<S, E> HasValue (object value, params object[] otherValues)
/// <summary>
/// Adds the hasValue step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> HasValue (TraversalPredicate predicate)
public GraphTraversal<S, E> HasValue (P predicate)
{
Bytecode.AddStep("hasValue", predicate);
return Wrap<S, E>(this);
Expand Down Expand Up @@ -888,7 +888,7 @@ public GraphTraversal<S, E> Is (object value)
/// <summary>
/// Adds the is step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> Is (TraversalPredicate predicate)
public GraphTraversal<S, E> Is (P predicate)
{
Bytecode.AddStep("is", predicate);
return Wrap<S, E>(this);
Expand Down Expand Up @@ -1660,7 +1660,7 @@ public GraphTraversal<S, E2> Values<E2> (params string[] propertyKeys)
/// <summary>
/// Adds the where step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> Where (TraversalPredicate predicate)
public GraphTraversal<S, E> Where (P predicate)
{
Bytecode.AddStep("where", predicate);
return Wrap<S, E>(this);
Expand All @@ -1669,7 +1669,7 @@ public GraphTraversal<S, E> Where (TraversalPredicate predicate)
/// <summary>
/// Adds the where step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal<S, E> Where (string startKey, TraversalPredicate predicate)
public GraphTraversal<S, E> Where (string startKey, P predicate)
{
Bytecode.AddStep("where", startKey, predicate);
return Wrap<S, E>(this);
Expand Down
106 changes: 79 additions & 27 deletions gremlin-dotnet/src/Gremlin.Net/Process/Traversal/P.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,85 +30,137 @@ namespace Gremlin.Net.Process.Traversal
/// A <see cref="P" /> is a predicate of the form Func&lt;object, bool&gt;.
/// That is, given some object, return true or false.
/// </summary>
public class P
public class P : IPredicate
{
/// <summary>
/// Initializes a new instance of the <see cref="P" /> class.
/// </summary>
/// <param name="operatorName">The name of the predicate.</param>
/// <param name="value">The value of the predicate.</param>
/// <param name="other">An optional other predicate that is used as an argument for this predicate.</param>
public P(string operatorName, dynamic value, P other = null)
{
OperatorName = operatorName;
Value = value;
Other = other;
}

/// <summary>
/// Gets the name of the predicate.
/// </summary>
public string OperatorName { get; }

/// <summary>
/// Gets the value of the predicate.
/// </summary>
public dynamic Value { get; }

/// <summary>
/// Gets an optional other predicate that is used as an argument for this predicate.
/// </summary>
public P Other { get; }

/// <summary>
/// Returns a composed predicate that represents a logical AND of this predicate and another.
/// </summary>
/// <param name="otherPredicate">A predicate that will be logically-ANDed with this predicate.</param>
/// <returns>The composed predicate.</returns>
public P And(P otherPredicate)
{
return new P("and", this, otherPredicate);
}

public static TraversalPredicate Between(params object[] args)
/// <summary>
/// Returns a composed predicate that represents a logical OR of this predicate and another.
/// </summary>
/// <param name="otherPredicate">A predicate that will be logically-ORed with this predicate.</param>
/// <returns>The composed predicate.</returns>
public P Or(P otherPredicate)
{
return new P("or", this, otherPredicate);
}

public static P Between(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("between", value);
return new P("between", value);
}

public static TraversalPredicate Eq(params object[] args)
public static P Eq(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("eq", value);
return new P("eq", value);
}

public static TraversalPredicate Gt(params object[] args)
public static P Gt(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("gt", value);
return new P("gt", value);
}

public static TraversalPredicate Gte(params object[] args)
public static P Gte(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("gte", value);
return new P("gte", value);
}

public static TraversalPredicate Inside(params object[] args)
public static P Inside(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("inside", value);
return new P("inside", value);
}

public static TraversalPredicate Lt(params object[] args)
public static P Lt(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("lt", value);
return new P("lt", value);
}

public static TraversalPredicate Lte(params object[] args)
public static P Lte(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("lte", value);
return new P("lte", value);
}

public static TraversalPredicate Neq(params object[] args)
public static P Neq(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("neq", value);
return new P("neq", value);
}

public static TraversalPredicate Not(params object[] args)
public static P Not(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("not", value);
return new P("not", value);
}

public static TraversalPredicate Outside(params object[] args)
public static P Outside(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("outside", value);
return new P("outside", value);
}

public static TraversalPredicate Test(params object[] args)
public static P Test(params object[] args)
{
var value = args.Length == 1 ? args[0] : args;
return new TraversalPredicate("test", value);
return new P("test", value);
}

public static TraversalPredicate Within(params object[] args)
public static P Within(params object[] args)
{
return new TraversalPredicate("within", args);
return new P("within", args);
}

public static TraversalPredicate Without(params object[] args)
public static P Without(params object[] args)
{
return new TraversalPredicate("without", args);
return new P("without", args);
}

/// <inheritdoc />
public override string ToString()
{
return Other == null ? $"{OperatorName}({Value})" : $"{OperatorName}({Value},{Other})";
}
}

#pragma warning restore 1591
Expand Down
Loading