예제 #1
0
async def get_or_create_edge(g: AsyncGraphTraversalSource,
                             edge: EdgeBase,
                             source_id: int = None,
                             target_id: int = None) -> tuple:
    """Create an edge if not existed before, if the given edge already exists, get its id.

    Optional parameters source_id and target_id are present for optimizations.
    """
    # If source_id/target_id are not provided explicitly and edge.source/edge.target are not set, this will raise
    # an exception. Provide at least one based on your usage.
    source_id = source_id or edge.source.id
    target_id = target_id or edge.target.id

    if EdgeBase.cache:
        item = edge.to_dict()
        item['source'] = source_id
        item['target'] = target_id
        try:
            cached_id = EdgeBase.cache.get(item)
            edge.id = cached_id
            return cached_id, True
        except CacheMiss:
            pass

    query = g.V(source_id).outE()
    creation = g.V(source_id).addE(edge.__label__)

    for key, value in edge.to_dict().items():
        if key in ('source', 'target', 'id'):
            continue

        # Goblin's to_dict() calls to_dict() on properties. If there is such case, get actual value from property.
        if isinstance(value, dict) and '__value__' in value:
            value = value['__value__']

        if value is not None:
            query = query.has(key, value)
            creation = creation.property(key, value)
        else:
            query = query.hasNot(key)

    result = await query.as_('e').inV().hasId(target_id).select(
        'e').fold().coalesce(
            unfold().id().as_('id').constant(True).as_('existed').select(
                'id', 'existed'),
            creation.as_('e').to(g.V(target_id)).select('e').id().as_(
                'id').constant(False).as_('existed').select('id',
                                                            'existed')).next()

    if EdgeBase.cache:
        item = edge.to_dict()
        # Overwrite source and target dict with actual id.
        item['source'] = source_id
        item['target'] = target_id
        EdgeBase.cache.put(item, result['id'])

    # Assign to instance so instance has the id associated correctly for later queries.
    edge.id = result['id']

    return result['id'], result['existed']
예제 #2
0
 def test_upsert(self) -> None:
     g = __.V().has('User', 'key', 'jack').fold().coalesce(
         unfold(),
         addV('User').property(Cardinality.single, 'key', 'jack')). \
         coalesce(__.has('email', '*****@*****.**'),
                  __.property(Cardinality.single, 'email', '*****@*****.**')). \
         coalesce(__.has('url', 'https://twitter.com/jack'),
                  __.property(Cardinality.single, 'url', 'https://twitter.com/jack'))
     actual = ScriptTranslator.translateB('g', g)
     self.assertEqual(
         actual,
         '''g.V().has("User","key","jack").fold().coalesce(__.unfold(),__.addV("User").property(single,"key","jack")).coalesce(__.has("email","*****@*****.**"),__.property(single,"email","*****@*****.**")).coalesce(__.has("url","https://twitter.com/jack"),__.property(single,"url","https://twitter.com/jack"))'''
     )  # noqa: E501
예제 #3
0
async def get_or_create_vertex(g: AsyncGraphTraversalSource,
                               vertex: VertexBase) -> tuple:
    """Create a vertex if not existes.

    If the Vertex does not exists, it is created, if the given vertex
    already exists, it's ID is returned.
    """
    if VertexBase.cache:
        try:
            cached_id = VertexBase.cache.get(vertex.to_dict())
            vertex.id = cached_id
            return cached_id, True
        except CacheMiss:
            pass

    query = g.V()
    creation = addV(vertex.__label__)

    for key, value in vertex.to_dict().items():
        # Goblin's to_dict() calls to_dict() on properties. If there is
        # such case, get actual value from property.
        if isinstance(value, dict) and '__value__' in value:
            value = value['__value__']
        if value is not None:
            query = query.has(key, value)
            creation = creation.property(key, value)
        else:
            query = query.hasNot(key)

    result = await query.fold().coalesce(
        unfold().id().as_('id').constant(True).as_('existed').select(
            'id', 'existed'),
        creation.id().as_('id').constant(False).as_('existed').select(
            'id', 'existed')).next()

    if VertexBase.cache:
        VertexBase.cache.put(vertex.to_dict(), result['id'])

    # Assign to instance so instance has the id associated correctly
    # for later queries.
    vertex.id = result['id']

    return result['id'], result['existed']
예제 #4
0
def select_current_vertex(traversal: GraphTraversal) -> GraphTraversal:

    return traversal.valueMap(True).by(unfold())