Ejemplo n.º 1
0
 def hydrate_(data, inst=None):
     if isinstance(data, dict):
         if "self" in data:
             if "type" in data:
                 return Relationship.hydrate(data["self"], inst=inst, **data)
             else:
                 return Node.hydrate(data["self"], inst=inst, **data)
         elif "nodes" in data and "relationships" in data:
             if "directions" not in data:
                 directions = []
                 relationships = graph.evaluate(
                     "MATCH ()-[r]->() WHERE id(r) IN {x} RETURN collect(r)",
                     x=[int(uri.rpartition("/")[-1]) for uri in data["relationships"]])
                 node_uris = data["nodes"]
                 for i, relationship in enumerate(relationships):
                     if remote(relationship.start_node()).uri == node_uris[i]:
                         directions.append("->")
                     else:
                         directions.append("<-")
                 data["directions"] = directions
             return Path.hydrate(data)
         else:
             # from warnings import warn
             # warn("Map literals returned over the Neo4j REST interface are ambiguous "
             #      "and may be hydrated as graph objects")
             return data
     elif is_collection(data):
         return type(data)(map(hydrate_, data))
     else:
         return data
Ejemplo n.º 2
0
 def hydrate_(obj, inst=None):
     # TODO: hydrate directly instead of via HTTP hydration
     if isinstance(obj, Structure):
         signature, args = obj
         if signature == b"N":
             uri = "%snode/%s" % (graph_uri, args[0])
             return Node.hydrate(uri,
                                 inst=inst,
                                 metadata={"labels": list(args[1])},
                                 data=hydrate_(args[2]))
         elif signature == b"R":
             uri = "%srelationship/%s" % (graph_uri, args[0])
             return Relationship.hydrate(
                 uri,
                 inst=inst,
                 start="%snode/%s" % (graph_uri, args[1]),
                 end="%snode/%s" % (graph_uri, args[2]),
                 type=args[3],
                 data=hydrate_(args[4]))
         elif signature == b"P":
             nodes = [hydrate_(node) for node in args[0]]
             u_rels = [
                 UnboundRelationship.hydrate(*map(hydrate_, r))
                 for _, r in args[1]
             ]
             sequence = args[2]
             last_node = nodes[0]
             steps = [last_node]
             for i, rel_index in enumerate(sequence[::2]):
                 next_node = nodes[sequence[2 * i + 1]]
                 last_node_uri = "%snode/%s" % (graph_uri,
                                                remote(last_node)._id)
                 next_node_uri = "%snode/%s" % (graph_uri,
                                                remote(next_node)._id)
                 if rel_index > 0:
                     u_rel = u_rels[rel_index - 1]
                     uri = "%srelationship/%s" % (graph_uri, u_rel.id)
                     rel = Relationship.hydrate(uri,
                                                start=last_node_uri,
                                                end=next_node_uri,
                                                type=u_rel.type,
                                                data=u_rel.properties)
                 else:
                     u_rel = u_rels[-rel_index - 1]
                     uri = "%srelationship/%s" % (graph_uri, u_rel.id)
                     rel = Relationship.hydrate(uri,
                                                start=next_node_uri,
                                                end=last_node_uri,
                                                type=u_rel.type,
                                                data=u_rel.properties)
                 steps.append(rel)
                 steps.append(next_node)
                 last_node = next_node
             return Path(*steps)
         else:
             # If we don't recognise the structure type, just return it as-is
             # TODO: add warning for unsupported structure types
             return obj
     elif isinstance(obj, list):
         return list(map(hydrate_, obj))
     elif isinstance(obj, dict):
         return {key: hydrate_(value) for key, value in obj.items()}
     else:
         return obj