Skip to content

Commit

Permalink
use traversal to add vertex, mostly to fix remote graph setups
Browse files Browse the repository at this point in the history
when using remote graphs, Graph is actually just an empty shell and
can't be used to e.g. add elements.

open problems:
* marshalled classes can use the @id annotation to specify
the ID of a vertex, but we cannot set the id of a vertex inside a traversal
* same needs to be applied for edges

re #223
  • Loading branch information
mpollmeier committed Feb 4, 2018
1 parent b7fad2f commit f740788
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 20 deletions.
44 changes: 25 additions & 19 deletions gremlin-scala/src/main/scala/gremlin/scala/ScalaGraph.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,22 @@ case class ScalaGraph(traversalSource: TraversalSource) {
def configure(conf: TraversalSource => TraversalSource) =
ScalaGraph(conf(TraversalSource(graph)))

def addVertex(label: String): Vertex = graph.addVertex(label)
def addVertex(): Vertex =
traversalSource.underlying.addV().next

def addVertex(): Vertex = graph.addVertex()
def addVertex(label: String): Vertex =
traversalSource.underlying.addV(label).next

def addVertex(label: String, properties: (String, Any)*): Vertex = {
val labelParam = Seq(T.label, label)
val params =
properties.flatMap(pair => Seq(pair._1, pair._2.asInstanceOf[AnyRef]))
graph.addVertex(labelParam ++ params: _*)
def addVertex(properties: (String, Any)*): Vertex = {
val traversal = traversalSource.underlying.addV()
properties.foreach { case (key, value) => traversal.property(key, value) }
traversal.next

This comment has been minimized.

Copy link
@rwilcox

rwilcox Feb 5, 2018

Woh, neat, auto calling next for me! (I think this is a good thing)

}

def addVertex(properties: (String, Any)*): Vertex = {
val params =
properties.flatMap(pair => Seq(pair._1, pair._2.asInstanceOf[AnyRef]))
graph.addVertex(params: _*)
def addVertex(label: String, properties: (String, Any)*): Vertex = {
val traversal = traversalSource.underlying.addV(label)
properties.foreach { case (key, value) => traversal.property(key, value) }
traversal.next
}

def addVertex(label: String, properties: Map[String, Any]): Vertex =
Expand All @@ -43,10 +44,13 @@ case class ScalaGraph(traversalSource: TraversalSource) {
/**
* Save an object's values into a new vertex
* @param cc The case class to persist as a vertex
*
* Note: this doesn't work with remote graphs, since remote graphs require you to use
* traversal steps to add a vertex (e.g. addV), but there's no step to set the ID

This comment has been minimized.

Copy link
@rwilcox

rwilcox Feb 5, 2018

We may be talking about different things here, but custom IDs for vertices and edges are only partially supported in JanusGraph: see JanusGraph/janusgraph#45

So if you're pulling your hair out about this particular issue, umm it might not be scala-gremlin's (or even gremlin's) fault.

This comment has been minimized.

Copy link
@mpollmeier

mpollmeier Feb 5, 2018

Author Owner

Yeah, I'm aware of that and will probably split up Graph and RemoteGraph

*/
def addVertex[CC <: Product: Marshallable](cc: CC): Vertex = {
val fromCC = implicitly[Marshallable[CC]].fromCC(cc)
val idParam = fromCC.id.toSeq.flatMap(List(T.id, _))
val idParam = fromCC.id.toSeq.flatMap(List(T.id, _)) //TODO: this will break things
val labelParam = Seq(T.label, fromCC.label)
val params = fromCC.valueMap.toSeq.flatMap(pair => Seq(pair._1, pair._2.asInstanceOf[AnyRef]))
graph.addVertex(idParam ++ labelParam ++ params: _*)
Expand All @@ -59,29 +63,31 @@ case class ScalaGraph(traversalSource: TraversalSource) {
def +(label: String, properties: KeyValue[_]*): Vertex =
addVertex(label, properties.map(v => (v.key.name, v.value)).toMap)

def inject[S](starts: S*): GremlinScala.Aux[S, HNil] =
GremlinScala[S, HNil](traversalSource.underlying.inject(starts: _*))

/** start a traversal with `addV` */
def addV(): GremlinScala.Aux[Vertex, HNil] =
GremlinScala[Vertex, HNil](traversalSource.underlying.addV())

/** start a traversal with `addV` */
def addV(label: String): GremlinScala.Aux[Vertex, HNil] =
GremlinScala[Vertex, HNil](traversalSource.underlying.addV(label))

def inject[S](starts: S*): GremlinScala.Aux[S, HNil] =
GremlinScala[S, HNil](traversalSource.underlying.inject(starts: _*))

// start traversal with all vertices
/** start traversal with all vertices */
def V(): GremlinScala.Aux[Vertex, HNil] =
GremlinScala[Vertex, HNil](traversalSource.underlying.V())

// start traversal with all edges
/** start traversal with all edges */
def E(): GremlinScala.Aux[Edge, HNil] =
GremlinScala[Edge, HNil](traversalSource.underlying.E())

// start traversal with some vertices identified by given ids
/** start traversal with some vertices identified by given ids */
def V(vertexIds: Any*): GremlinScala.Aux[Vertex, HNil] =
GremlinScala[Vertex, HNil](
traversalSource.underlying.V(vertexIds.asInstanceOf[Seq[AnyRef]]: _*))

// start traversal with some edges identified by given ids
/** start traversal with some edges identified by given ids */
def E(edgeIds: Any*): GremlinScala.Aux[Edge, HNil] =
GremlinScala[Edge, HNil](traversalSource.underlying.E(edgeIds.asInstanceOf[Seq[AnyRef]]: _*))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class ElementSpec extends TestBase {
* TODO: `properties` should take `Key` as well
*/
it("sets a property with multiple values") {
val v = graph.addV().property(Name, "marko").property(Name, "marko a. rodriguez").head
val v = graph.addVertex((Name.name -> "marko"), (Name.name -> "marko a. rodriguez"))
graph.V(v).properties(Name.name).count.head shouldBe 2

v.property(Cardinality.list, Name.name, "m. a. rodriguez")
Expand Down

0 comments on commit f740788

Please sign in to comment.