rtags.py
author sylvain.thenault@logilab.fr
Fri, 27 Mar 2009 12:30:19 +0100
branchtls-sprint
changeset 1179 70825477c6ce
parent 1152 c99ef2a2535c
child 1283 d812bd08c11c
permissions -rw-r--r--
fix *relations_by_categories + rtags api/key mess
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1152
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     1
"""relation tags store
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     2
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     3
:organization: Logilab
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     6
"""
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     7
__docformat__ = "restructuredtext en"
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
     8
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
     9
class RelationTags(object):
1152
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    10
    """RelationTags instances are a tag store for full relation definitions :
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    11
1152
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    12
         (subject type, relation type, object type, role)
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    13
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    14
    allowing to set tags using wildcard (eg '*') as subject type / object type
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    15
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    16
    if `use_set` is True, a set of tags is associated to each key, and you
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    17
    should use rtags / etype_rtags / add_rtag api. Otherwise, a single tag is
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    18
    associated to each key, and you should use rtag / etype_rtag / set_rtag api.
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    19
    """
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    20
    
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    21
    def __init__(self, use_set=False):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    22
        self.use_set = use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    23
        self._tagdefs = {}
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    24
        
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    25
    def set_rtag(self, tag, rtype, role, stype='*', otype='*'):
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    26
        assert not self.use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    27
        assert role in ('subject', 'object'), role
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    28
        self._tagdefs[(rtype, role, stype, otype)] = tag
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    29
        
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    30
    def rtag(self, rtype, role, stype='*', otype='*'):
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    31
        assert not self.use_set
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    32
        for key in reversed(self._get_keys(rtype, role, stype, otype)):
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    33
            try:
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    34
                return self._tagdefs[key]
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    35
            except KeyError:
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    36
                continue
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    37
        return None
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    38
        
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    39
    def etype_rtag(self, etype, rtype, role, ttype='*'):
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    40
        if role == 'subject':
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    41
            return self.rtag(rtype, role, etype, ttype)
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    42
        return self.rtag(rtype, role, ttype, etype)
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    43
        
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    44
    def add_rtag(self, tag, rtype, role, stype='*', otype='*'):
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    45
        assert self.use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    46
        assert role in ('subject', 'object'), role
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    47
        rtags = self._tagdefs.setdefault((rtype, role, stype, otype), set())
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    48
        rtags.add(tag)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    49
        
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    50
    def rtags(self, rtype, role, stype='*', otype='*'):
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    51
        assert self.use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    52
        rtags = set()
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    53
        for key in self._get_keys(rtype, role, stype, otype):
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    54
            try:
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    55
                rtags.update(self._tagdefs[key])
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    56
            except KeyError:
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    57
                continue
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    58
        return rtags
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    59
        
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    60
    def etype_rtags(self, etype, rtype, role, ttype='*'):
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    61
        if role == 'subject':
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    62
            return self.rtags(rtype, role, etype, ttype)
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    63
        return self.rtags(rtype, role, ttype, etype)
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    64
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    65
    def _get_keys(self, rtype, role, stype, otype): 
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    66
        assert role in ('subject', 'object'), role
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    67
        keys = [(rtype, role, '*', '*'),
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    68
                (rtype, role, '*', otype),
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    69
                (rtype, role, stype, '*'),
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    70
                (rtype, role, stype, otype)]
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    71
        if stype == '*' or otype == '*':
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    72
            keys.remove((rtype, role, '*', '*'))
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    73
            if stype == '*':
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    74
                keys.remove((rtype, role, '*', otype))
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    75
            if otype == '*':
1179
70825477c6ce fix *relations_by_categories + rtags api/key mess
sylvain.thenault@logilab.fr
parents: 1152
diff changeset
    76
                keys.remove((rtype, role, stype, '*'))            
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    77
        return keys
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    78
    
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    79
    # dict compat
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    80
    def __getitem__(self, key):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    81
        if isinstance(key, basestring):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    82
            key = (key,)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    83
        return self.rtags(*key)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    84
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    85
    __contains__ = __getitem__