rtags.py
changeset 3472 5345570eefc6
parent 2689 44f041222d0f
child 3473 d8bc02158efc
equal deleted inserted replaced
3471:8c57c71b859c 3472:5345570eefc6
    12 from logilab.common.logging_ext import set_log_methods
    12 from logilab.common.logging_ext import set_log_methods
    13 
    13 
    14 RTAGS = []
    14 RTAGS = []
    15 def register_rtag(rtag):
    15 def register_rtag(rtag):
    16     RTAGS.append(rtag)
    16     RTAGS.append(rtag)
       
    17 
       
    18 def _ensure_str_key(key):
       
    19     return tuple(str(k) for k in key)
    17 
    20 
    18 class RelationTags(object):
    21 class RelationTags(object):
    19     """a tag store for full relation definitions :
    22     """a tag store for full relation definitions :
    20 
    23 
    21          (subject type, relation type, object type, tagged)
    24          (subject type, relation type, object type, tagged)
    43 
    46 
    44     def clear(self):
    47     def clear(self):
    45         self._tagdefs.clear()
    48         self._tagdefs.clear()
    46 
    49 
    47     def _get_keys(self, stype, rtype, otype, tagged):
    50     def _get_keys(self, stype, rtype, otype, tagged):
    48         keys = [(rtype, tagged, '*', '*'),
    51         keys = [('*', rtype, '*', tagged),
    49                 (rtype, tagged, '*', otype),
    52                 ('*', rtype, otype, tagged),
    50                 (rtype, tagged, stype, '*'),
    53                 (stype, rtype, '*', tagged),
    51                 (rtype, tagged, stype, otype)]
    54                 (stype, rtype, otype, tagged)]
    52         if stype == '*' or otype == '*':
    55         if stype == '*' or otype == '*':
    53             keys.remove((rtype, tagged, '*', '*'))
    56             keys.remove( ('*', rtype, '*', tagged) )
    54             if stype == '*':
    57             if stype == '*':
    55                 keys.remove((rtype, tagged, '*', otype))
    58                 keys.remove( ('*', rtype, otype, tagged) )
    56             if otype == '*':
    59             if otype == '*':
    57                 keys.remove((rtype, tagged, stype, '*'))
    60                 keys.remove( (stype, rtype, '*', tagged) )
    58         return keys
    61         return keys
    59 
    62 
    60     def init(self, schema, check=True):
    63     def init(self, schema, check=True):
    61         # XXX check existing keys against schema
    64         # XXX check existing keys against schema
    62         if check:
    65         if check:
    63             for (rtype, tagged, stype, otype), value in self._tagdefs.items():
    66             for (stype, rtype, otype, tagged), value in self._tagdefs.items():
    64                 for ertype in (stype, rtype, otype):
    67                 for ertype in (stype, rtype, otype):
    65                     if ertype != '*' and not ertype in schema:
    68                     if ertype != '*' and not ertype in schema:
    66                         self.warning('removing rtag %s: %s, %s undefined in schema',
    69                         self.warning('removing rtag %s: %s, %s undefined in schema',
    67                                      (stype, rtype, otype, tagged), value, ertype)
    70                                      (stype, rtype, otype, tagged), value, ertype)
    68                         self.del_rtag(stype, rtype, otype, tagged)
    71                         self.del_rtag(stype, rtype, otype, tagged)
   101         stype, rtype, otype, tagged = [str(k) for k in key]
   104         stype, rtype, otype, tagged = [str(k) for k in key]
   102         if self._allowed_values is not None:
   105         if self._allowed_values is not None:
   103             assert tag in self._allowed_values, \
   106             assert tag in self._allowed_values, \
   104                    '%r is not an allowed tag (should be in %s)' % (
   107                    '%r is not an allowed tag (should be in %s)' % (
   105                 tag, self._allowed_values)
   108                 tag, self._allowed_values)
   106         self._tagdefs[(rtype, tagged, stype, otype)] = tag
   109         self._tagdefs[_ensure_str_key(key)] = tag
   107         return tag
   110         return tag
   108 
   111 
   109     # rtag runtime api ########################################################
   112     # rtag runtime api ########################################################
   110 
   113 
   111     def del_rtag(self, stype, rtype, otype, tagged):
   114     def del_rtag(self, *key):
   112         del self._tagdefs[(rtype, tagged, stype, otype)]
   115         del self._tagdefs[key]
   113 
   116 
   114     def get(self, stype, rtype, otype, tagged):
   117     def get(self, stype, rtype, otype, tagged):
   115         for key in reversed(self._get_keys(stype, rtype, otype, tagged)):
   118         for key in reversed(self._get_keys(stype, rtype, otype, tagged)):
   116             try:
   119             try:
   117                 return self._tagdefs[key]
   120                 return self._tagdefs[key]
   130     """This class associates a set of tags to each key.
   133     """This class associates a set of tags to each key.
   131     """
   134     """
   132     tag_container_cls = set
   135     tag_container_cls = set
   133 
   136 
   134     def tag_relation(self, key, tag):
   137     def tag_relation(self, key, tag):
   135         stype, rtype, otype, tagged = [str(k) for k in key]
   138         rtags = self._tagdefs.setdefault(_ensure_str_key(key),
   136         rtags = self._tagdefs.setdefault((rtype, tagged, stype, otype),
       
   137                                          self.tag_container_cls())
   139                                          self.tag_container_cls())
   138         rtags.add(tag)
   140         rtags.add(tag)
   139         return rtags
   141         return rtags
   140 
   142 
   141     def get(self, stype, rtype, otype, tagged):
   143     def get(self, stype, rtype, otype, tagged):
   151 class RelationTagsDict(RelationTagsSet):
   153 class RelationTagsDict(RelationTagsSet):
   152     """This class associates a set of tags to each key."""
   154     """This class associates a set of tags to each key."""
   153     tag_container_cls = dict
   155     tag_container_cls = dict
   154 
   156 
   155     def tag_relation(self, key, tag):
   157     def tag_relation(self, key, tag):
   156         stype, rtype, otype, tagged = [str(k) for k in key]
   158         key = _ensure_str_key(key)
   157         try:
   159         try:
   158             rtags = self._tagdefs[(rtype, tagged, stype, otype)]
   160             rtags = self._tagdefs[key]
   159             rtags.update(tag)
   161             rtags.update(tag)
   160             return rtags
   162             return rtags
   161         except KeyError:
   163         except KeyError:
   162             self._tagdefs[(rtype, tagged, stype, otype)] = tag
   164             self._tagdefs[key] = tag
   163             return tag
   165             return tag
   164 
   166 
   165     def setdefault(self, key, tagkey, tagvalue):
   167     def setdefault(self, key, tagkey, tagvalue):
   166         stype, rtype, otype, tagged = [str(k) for k in key]
   168         key = _ensure_str_key(key)
   167         try:
   169         try:
   168             rtags = self._tagdefs[(rtype, tagged, stype, otype)]
   170             rtags = self._tagdefs[key]
   169             rtags.setdefault(tagkey, tagvalue)
   171             rtags.setdefault(tagkey, tagvalue)
   170             return rtags
   172             return rtags
   171         except KeyError:
   173         except KeyError:
   172             self._tagdefs[(rtype, tagged, stype, otype)] = {tagkey: tagvalue}
   174             self._tagdefs[key] = {tagkey: tagvalue}
   173             return self._tagdefs[(rtype, tagged, stype, otype)]
   175             return self._tagdefs[key]
   174 
   176 
   175 
   177 
   176 class RelationTagsBool(RelationTags):
   178 class RelationTagsBool(RelationTags):
   177     _allowed_values = frozenset((True, False))
   179     _allowed_values = frozenset((True, False))
   178 
   180