graphalchemy / graphalchemy / mixins / elements.py

# -*- coding: utf-8 -*-
'''graph element mixins'''

from stuf.utils import both, getcls, lazy, clsname

from graphalchemy.core import octopus, factory, app

__all__ = ('ElementMixin', 'NodesMixin')
# settings
conf = octopus.G
backends = conf.backends
db = conf.key.db


class ElementMixin(object):

    '''graph element'''

    # graph source
    _db = app(conf.key.backend, conf.userspace)
    # node reader
    _lr = _r = factory(conf.read.link, backends, db)
    # node writer
    _lw = _w = factory(conf.write.link, backends, db)
    # links collection
    _links = app(conf.direct.collector.link, conf.directs)

    def __init__(self, element=None, **kw):
        '''
        init

        @param element: graph element (default: None)
        '''
        # element direction
        self.direction = kw.pop('direction', 'outgoing')
        super(ElementMixin, self).__init__(element, **kw)

    def __repr__(self):
        return '{0}: {1}'.format(
            clsname(self), super(ElementMixin, self).__repr__(),
        )

    @lazy
    def id(self):
        '''graph element id'''
        return self._r.id(self.source)

    @both
    def links(self):
        '''sequence of all links'''
        return self._links(self, getcls(self))

    def _source(self, element):
        '''
        synchronized data structure

        @param element: this element
        '''
        return self._r.properties(element)

    def _refresh(self):
        '''refresh original'''
        # reset links collector
        self.links.reset()

    def index_by(self, index=None, *indexed):
        '''
        index properties on a graph element

        @param index: graph index label (default: None)
        @param *indexed: properties to index
        '''
        self._r.index_many(index, self, indexed)

    def index_under(self, index, key, value):
        '''
        index one property of a graph element

        @param index: graph index label
        @param key: graph element property key
        @param value: graph element property value
        '''
        self._r.index_one(index, key, value, self)


class NodeMixin(object):

    '''node element'''

    # node reader
    _nr = _r = factory(conf.read.node, backends, db)
    # node writer
    _nw = _w = factory(conf.write.node, backends, db)

    @lazy
    def nodes(self):
        '''connector to all nodes linked to this node'''
        return self._nodes(self, getcls(self))

    def _refresh(self):
        '''refresh node objects'''
        super(NodeMixin, self)._refresh()
        # reset nodes connector
        self.nodes.reset()

    def deep_dump(self):
        '''
        serialize this node, its outgoing related nodes, and their outgoing
        related nodes
        '''
        return self.copy(id=self.id, nodes=self.nodes.deep_dump())

    def dump(self):
        '''serialize this node and outgoing related nodes'''
        return self.copy(id=self.id)

    def link(self, link, node, **kw):
        '''
        link this node to another node

        @param link: kind of link
        @param node: the other node
        @param **kw: link properties
        '''
        self._lw.create(link, self, node, kw)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.