[ 
https://issues.apache.org/jira/browse/TINKERPOP-2502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17267638#comment-17267638
 ] 

Christopher Smith commented on TINKERPOP-2502:
----------------------------------------------

I'm writing what's essentially a mini-OGM for Groovy, to be eventually 
implemented as a set of compile-time AST transformations to generate the 
repetitive part of mapping traversals. This is an extension method (in Java) 
that allows writing {{gts.addV(newPerson, PERSON_WRITER)}} (the logic might 
look familiar):

{code:java}
@SuppressWarnings("unchecked") // both traversal paths end in a Vertex
public static <V extends HasLabelAndId> GraphTraversal<Vertex, Vertex> 
addV(GraphTraversalSource self, V entity, VertexWriter<V> writer) {
    // https://stackoverflow.com/a/46053115/1189885
    return self
            .V(entity.getLabelAndId().getId()).fold()
            .coalesce(
                    whenExists(true, unfold()),
                    whenExists(false, writer.createVertex(start(), entity))
            )
            .filter(select("existed").is(false))
            .select("element");
}

private static <A> GraphTraversal<A, Map<String, Object>> whenExists(boolean 
exists, GraphTraversal<A, ?> gt) {
    return gt.project("element", "existed").by(identity()).by(constant(exists));
}
{code}

However, this method can _only_ be called as {{gts.addV}}; it _cannot_ be 
called as {{__.addV}}, because there is no common supertype. Furthermore, while 
in the anonymous case (say, creating multiple vertices with edges between them) 
I could call {{__.start()}} to get a traversal to feed to the pipeline above, 
as I do to pass to {{createVertex}}, if I already have a 
{{GraphTraversalSource}} there's no way to turn it into a {{GraphTraversal}} 
except through {{V}}, {{E}}, {{addV}}, {{addE}}, or {{inject}} (potentially 
problematic with some implementations).

Instead, if I had a method such as {{GraphTraversalSource#start()}} with the 
obvious semantics, I could modify the above method to accept a 
{{GraphTraversal}}, consume it for both anonymous and regular traversals, and 
provide sugar to adapt those cases onto it.

> Consistent start API for anonymous and regular traversals
> ---------------------------------------------------------
>
>                 Key: TINKERPOP-2502
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2502
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: process
>    Affects Versions: 3.4.9
>            Reporter: Christopher Smith
>            Priority: Minor
>
> I am writing a graph-based application and am taking advantage of the 
> method-based nature of Gremlin to librarify some of my common usage patterns. 
> However, I'm encountering a frustrating problem where I frequently need to be 
> able to attach the same traversal steps to either a real 
> {{GraphTraversalSource}} or an anonymous traversal (usually for some nested 
> reason like a coalesced conditional insert).
> The methods on {{__}} are mostly static, but I can call {{__.start()}} to 
> obtain a live {{GraphTraversal}} object and then proceed from there (invoking 
> {{GraphTraversal#addV}}, for example). {{GraphTraversalSource}}, however, 
> requires me to invoke the method {{GraphTraversalSource#addV}} to get 
> started, and there's no common base type. I think I could theoretically use 
> something like {{inject()}}, but that seems particularly odd.
> It would be helpful to either have both {{GraphTraversal}} and 
> {{GraphTraversalSource}} implement a common interface holding the "start 
> opcodes" or to have a {{GraphTraversalSource#start()}} method that could be 
> used to obtain a "blank" traversal.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to