$db = new Connection(['host' => 'localhost','graph' => 'graph','username' => 'pomme','password' => 'hardToCrack']);//you can set $db->timeout = 0.5; if you wish$db->open();$db->send('g.V(2)');//do something with result$db->close();
public class Test {String s;public Test(final String source) {s = source;}public Test() {s = "";}public Test V() {s = s + ".V()";return this;}public Test outE(final String label) {s = s + ".outE(\"${label}\")";return this;}public Test repeat(final Test test) {s = s + ".repeat(${test.toString()})";return this;}public String toString() {return s;}}
gremlin> g = new Test("g");==>ggremlin> g.V().outE("knows")==>g.V().outE("knows")gremlin>gremlin> g = new Test("g");==>ggremlin> g.V().repeat(new Test().outE("knows"))==>g.V().repeat(.outE("knows"))gremlin>
$g->V->outE("knows")
--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/47A92EFF-CB36-41EA-B252-6823A42F4D7B%40gmail.com.
For more options, visit https://groups.google.com/d/optout.
1. Method overloading :abstract class Query {public function has(PropertyKey $key); //1public function has(PropertyKey $key, Object $value); //2
public function has(Label $label, String $value); //3
public function has(VertexId $id, Long $value); //4
public function has(VertexId $id, Int $value); //5
public function has(VertexId $id, Predicate $p); //6}The above is illegal in languages like PHP (or javascript?). Instead we're stuck with :abstract class Query {public function has(Array $args);}We're then left to figure out what is what in the array and sort out how we need to stringify the output.
If the user does $g->V()->has("label", "user") do we add quotes to the first argument or is it a label/id? What about the second argument, is it a predicate? etc. This gets complexe very quickly.
And what if I had $g->V()->has("id", 36) . PHP only supports Int so one of the two signatures (4 or 5) needs to give as we have a major conflict. This example is fictional for has() but I've run into this on a couple of other methods, just can't remember which.
Another example would be g.V().has(id, neq(m)) . We could imagine the following PHP equivalent $g->V()->has(new Id(), Predicate::neq("m")) where Id() is a class that helps us recognize this type, and neq() a static method of Predicate. However "m" has to be passed as string and we have no clue what m is... is this a string or a binding or a server side variable? More on this in point 2.
To close things off here there's also the case of signatures like out(String... edgeLabels) that need their own logic.
Conclusion: There's a lot of manual work that needs to go into separating the logic between signatures and handling special cases. Part of this can be automated if your language supports magic getters and setters by parsing the javadocs for example. But not only is that an if, the rest will still be manual. This step is maintenance heavy.
2. ConflictsBecause we're manipulating strings it's really hard to tell a few items appart (binding vs server variable vs string; Theres a reason why I separate binding and variable).For instance in the example above of gremlin : g.V().has(id, neq(m)) vs PHP: $g->V()->has(new Id(), Predicate::neq("m")) we don't know what to make of m. Is this a binding or a string or even a variable that was previously set in the session? There is no clean way of working around this.Firstly because bindings tend to be handled on a different layer than the query builder.Secondly because methods that will help in avoiding the conflicts will also lose typing data.For example : $g->V()->has(new Id(), Predicate::neq(Query::variable("m"))) could generate the proper query by outputting m without quotes but we don't know what type m is so in some cases it might be tricky to select the proper signature.Conclusion: there are a number of ways around this point. We use prefixes B_m or V_m and a hack to ignore signatures altogether when in this scenario. It's not that these aren't solve-able they just aren't trivial.
3. APIWhy we would need traversal, graph, vertex and edge APIs are quite self explanatory for everyday work with Gremlin. I'm just going to expose why we would also require some Java classes as well.Because JSON is lossy by nature we often have to cast variables to certain types. For example by submitting these kind of scripts : g.V(1).property("date", new Date(B_m)); with B_m = timestamp. This is just another case that is difficult to cover.This adds onto the other points in making a gremlin language variant non-trivial.All of the above can be worked around by using an injection method that just appends a string to the query : $g->customStep("V().has(id, neq(m))") but that's besides the point.
if(object instanceof String)return \" + object.toString() + "\;else if(object instanceof Date)return "new Date(…)";elsereturn object.toString()
Final Conclusion: It's not a trivial task. Of course the examples above are very verbose and achieving something closer to gremlin in style is possible but there are always going to be "gotchas" users will need to keep in mind. A while back in TP2 I released a php library for this (the one we currently use in our projects). I decided to remove it as it was too much maintenance to get it to work across user causes so I decided to concentrate on our own one (some choices made in 2. wouldn't have worked for other cases)I'm convinced there's got to be a way of reconciling everything and getting this to work flawlessly but it's going to require a lot of thought/workPS: I mentioned some other points like managing multiple versions of gremlin (for two lines of releases) which is a real headache.For performance it may be good to allow the builder to handle multiple lines, which comes with it's load of complications as well.And then there's the ability to "block" queries and either inject them into each other or merge them together which simplifies unit testing and extends functionality :$query = $g->V()->out("likes")->flag("flagname")->has("age", 20);// Some logic here accesses new information and realizes the query needs altering$query->getFlag("flagname")->out("hates", true) // true for merge$query->toString(); // g.V().out('likes', hates').has('age', 20)But this point alone could warrant it's own email as it is relatively complex. Though TP3 has simplified some cases thanks to union() and some other steps.Our builder supports all of the above so if you have any questions feel free to ask me.Phew that was long. I'll add this to the ticket in a bit.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/CAE0QJeqntbEk70yg_d2SACxaKxA995Z8SL5_3JRaxzsQCCOMbw%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/B0319D4D-9834-47E3-9743-522BA13060A9%40gmail.com.
$g= Gremlin();
$g->V()->has('"name"','mark');
echo (str)$g; //g.V().has("name",SOME_BOUND_VAR_1)res = g.V() # sends request
res2 = g.V().has('"name"', 'mark') # second request
...
res = g.V().has('"name"',{'NAME':'mark'}) # g.V().has("name",NAME)To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/600cc5c0-99f0-4bf9-9be6-92b7a9a58838%40googlegroups.com.
...
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/27e000ac-39c1-415d-bd3c-48c40febc97d%40googlegroups.com.
...
A logo would be awesome! Thanks.
I'd love to help with the tutorial. I think it will not only help the Gremlin community, but the library will get a lot better as a result. Just let me know where to start and what you'd like to see.

--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/e7eb7ab6-3455-4b71-ad39-18094f2e06aa%40googlegroups.com.
...
...
--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/b0e6a46e-9fd4-4139-9d6d-a96038be52e0%40googlegroups.com.
Depends on perception, there doesn't seem to be many from my perspective. To clarify Goblin is Mogwai's successor and it has ZeroFail behind it, which is the only one with sponsored adoption that I'm aware of (unless bulbs is too). There are a couple incarnations of the rexpro interface (one I currently maintain for Titan <0.9.x ), gremlinpy a very nifty syntax mirror, and a couple HTTP clients like bulbs. I really only see 2 major full featured OGM libraries (Goblin & bulbs), and a handful of communication/utility libraries.
A couple of choices is a good thing as one library's opinionated operation may not fit your problem, but another might. Some people really may just want a communication + syntax mirror and are perfectly happy with raw python type responses, others may prefer something like an OGM that is linked to their Object Models, and some mixed mode? Not to mention the different programming paradigms.
Ah I totally spaced on gizmo! Sorry Mark!
You received this message because you are subscribed to a topic in the Google Groups "Gremlin-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/gremlin-users/kTXEzJE8wEs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/49556108-6177-4d53-bb93-14d52e0b7e8f%40googlegroups.com.