Exemple #1
0
    def get_edge_by_uuid(self, edge_name, uuid):
        """retrieves a edge by id

        :param edge_name: the edge name or type
        :param uuid: the uuid value
        """
        edge_name = resolve_edge_name(edge_name)
        pattern = os.sep.join([edge_name, '_ids', uuid])
        for entry in self.glob(pattern):
            edge_blob_id = self.repository[entry.oid].data
            blob = self.repository[edge_blob_id]
            return Edge.from_data(edge_name, **self.deserialize(blob.data))
Exemple #2
0
    def scan_all(self, edge_name=None, treeish=None, pattern='*'):
        """scans all nodes

        :returns: a generator that produces :py:class:`Edge` instances with the scanned data
        """
        edge_name = resolve_edge_name(edge_name)
        treeish = treeish or self.repository.index
        pattern = os.path.join(edge_name, 'objects', pattern)
        for entry in self.glob(pattern):
            blob = self.repository[entry.oid]
            data = self.deserialize(blob.data)
            yield Edge.from_data(edge_name, **data)
Exemple #3
0
    def add_spo(self, edge, predicate, data):
        """creates a staged entry of edge, predicate and object

        :param edge:
        :param predicate:
        :param data:
        :returns: ``bytes`` - the blob id
        """
        edge = resolve_edge_name(edge)
        blob_id = self.repository.create_blob(data)
        entry = IndexEntry(os.path.join(edge, predicate), blob_id,
                           GIT_FILEMODE_BLOB)
        self.repository.index.add(entry)
        return blob_id
Exemple #4
0
def test_resolve_edge_name():
    'resolve_edge_name() should return a string'

    resolve_edge_name('Vehicle').should.equal('Vehicle')
    resolve_edge_name(None).should.equal('*')
    resolve_edge_name(Vehicle).should.equal('Vehicle')
    resolve_edge_name.when.called_with({}).should.have.raised(
        TypeError,
        'resolve_edge_name() takes a Edge subclass, a string or None. Got {}'
    )
Exemple #5
0
    def match_edges_by_index(self, edge_name, field_name, match_callback):
        """retrieves multiple edges by indexed field

        :param edge_name: the edge name or type
        :param uuid: the uuid value
        """
        edge_name = resolve_edge_name(edge_name)
        pattern = os.sep.join([edge_name or '*', 'indexes', '*'])
        # for index, oid in filter(lambda (index, oid): field_name in index, self.glob(pattern)):
        for index, oid in self.trace_path(self.glob(pattern)):
            path, blob_id = os.path.split(index)
            edge_name = path.split(os.sep)[0]
            value = self.repository[oid].data
            if match_callback(value):
                blob = self.repository[blob_id]
                data = self.deserialize(blob.data)
                Definition = Edge.definition(edge_name)
                yield Definition(**data)
Exemple #6
0
    def create_edge(self, edge, **obj):
        """creates a staged edge entry including its indexed fields.

        :param edge: a string or a :py:class:`Edge` subclass reference
        :param ``**kw``: the field values
        :returns: an instance of the given edge

        """
        predicate_ids = []

        edge = resolve_edge_name(edge)
        edge_uuid = obj.pop('uuid', generate_uuid())
        obj['uuid'] = edge_uuid

        edge_data = self.serialize(obj)
        object_hash = bytes(pygit2.hash(edge_data))
        object_path = os.path.join(edge, 'objects')

        id_path = os.path.join(edge, '_ids')
        uuid_path = os.path.join(edge, '_uuids')

        indexes = {}
        for key in obj.keys():
            value = obj.get(key, None)
            if edge_has_index(edge, key):
                indexes[key] = value

            predicate_path = os.path.join(edge, 'indexes', key)
            predicate_ids.append(
                self.add_spo(predicate_path, object_hash, value))

        self.add_spo(object_path, object_hash, edge_data)
        self.add_spo(id_path, edge_uuid, object_hash)
        self.add_spo(uuid_path, object_hash, edge_uuid)

        return Edge.from_data(edge, **obj)
Exemple #7
0
    def create_vertex(self, vertex, **obj):
        """creates a staged vertex entry including its indexed fields.

        :param vertex: a string or a :py:class:`Vertex` subclass reference
        :param ``**kw``: the field values
        :returns: an instance of the given vertex

        """
        vertex = resolve_vertex_name(vertex)
        predicate_ids = []

        vertex_uuid = obj.pop('uuid', generate_uuid())
        obj['uuid'] = vertex_uuid

        vertex_data = self.serialize(obj)
        object_hash = bytes(pygit2.hash(vertex_data))
        object_path = os.path.join(vertex, 'objects')

        id_path = os.path.join(vertex, '_ids')
        uuid_path = os.path.join(vertex, '_uuids')

        original_obj = obj.copy()
        origin = obj.pop('origin')
        target = obj.pop('target')

        indexes = {}
        for key in obj.keys():
            value = obj.get(key, None)
            if vertex_has_index(vertex, key):
                indexes[key] = value

            predicate_path = os.path.join(vertex, 'indexes', key)
            predicate_ids.append(
                self.add_spo(predicate_path, object_hash, value))

        self.add_spo(id_path, vertex_uuid, object_hash)
        self.add_spo(uuid_path, object_hash, vertex_uuid)

        origin_name = resolve_edge_name(origin)
        target_name = resolve_edge_name(target)
        RelationhipModel = Vertex.definition(vertex)

        label = RelationhipModel.label
        # call('Car/incoming/bought_by/Person', 'chuck-uuid', 'car-uuid'),
        # call('___vertices___/Car/bought_by/Person', 'chuck-uuid', 'car-uuid'),
        path_templates = {
            'incoming': '{to}/incoming/{label}/{from}',
            'outgoing': '{from}/outgoing/{label}/{to}',
            'indirect': '{}/indirect/{label}/{}',
        }
        vertex_path_template = path_templates[RelationhipModel.direction]

        ctx = {'label': label}
        direction = RelationhipModel.direction
        # self.add_spo(object_path, object_hash, vertex_data)

        if direction == 'incoming':
            from_uuid = origin.uuid
            ctx['from'] = origin_name
            to_uuid = target.uuid
            ctx['to'] = target_name
            vertex_path = vertex_path_template.format(**ctx)
            self.add_spo(vertex_path, from_uuid, to_uuid)

        elif direction == 'outgoing':
            from_uuid = target.uuid
            ctx['from'] = target_name
            to_uuid = origin.uuid
            ctx['to'] = origin_name
            vertex_path = vertex_path_template.format(**ctx)
            self.add_spo(vertex_path, from_uuid, to_uuid)

        elif direction == 'indirect':
            from_uuid = target.uuid
            to_uuid = origin.uuid

            path = vertex_path_template.format(target_name, origin_name, **ctx)
            self.add_spo(path, from_uuid, to_uuid)

            path = vertex_path_template.format(origin_name, target_name, **ctx)
            self.add_spo(path, to_uuid, from_uuid)

        return RelationhipModel.from_data(vertex, **original_obj)