entity.py
branchstable
changeset 1840 f4b5c15d1147
parent 1804 1ce3474dac43
child 1842 c7a22540d6f7
equal deleted inserted replaced
1839:2cdd0d1d3888 1840:f4b5c15d1147
   282     def parent_classes(cls):
   282     def parent_classes(cls):
   283         parents = [cls.vreg.etype_class(e.type) for e in cls.e_schema.ancestors()]
   283         parents = [cls.vreg.etype_class(e.type) for e in cls.e_schema.ancestors()]
   284         parents.append(cls.vreg.etype_class('Any'))
   284         parents.append(cls.vreg.etype_class('Any'))
   285         return parents
   285         return parents
   286 
   286 
       
   287     @classmethod
       
   288     @cached
       
   289     def _rest_attr_info(cls):
       
   290         mainattr, needcheck = 'eid', True
       
   291         if cls.rest_attr:
       
   292             mainattr = cls.rest_attr
       
   293             needcheck = not cls.e_schema.has_unique_values(mainattr)
       
   294         else:
       
   295             for rschema in cls.e_schema.subject_relations():
       
   296                 if rschema.is_final() and rschema != 'eid' and cls.e_schema.has_unique_values(rschema):
       
   297                     mainattr = str(rschema)
       
   298                     needcheck = False
       
   299                     break
       
   300         if mainattr == 'eid':
       
   301             needcheck = False
       
   302         return mainattr, needcheck
       
   303 
   287     def __init__(self, req, rset=None, row=None, col=0):
   304     def __init__(self, req, rset=None, row=None, col=0):
   288         AppRsetObject.__init__(self, req, rset, row, col)
   305         AppRsetObject.__init__(self, req, rset, row, col)
   289         dict.__init__(self)
   306         dict.__init__(self)
   290         self._related_cache = {}
   307         self._related_cache = {}
   291         if rset is not None:
   308         if rset is not None:
   361         # the object for use in the relation is tricky
   378         # the object for use in the relation is tricky
   362         # XXX search_state is web specific
   379         # XXX search_state is web specific
   363         if getattr(self.req, 'search_state', ('normal',))[0] == 'normal':
   380         if getattr(self.req, 'search_state', ('normal',))[0] == 'normal':
   364             kwargs['base_url'] = self.metainformation()['source'].get('base-url')
   381             kwargs['base_url'] = self.metainformation()['source'].get('base-url')
   365         if method is None or method == 'view':
   382         if method is None or method == 'view':
   366             kwargs['_restpath'] = self.rest_path()
   383             kwargs['_restpath'] = self.rest_path(kwargs.get('base_url'))
   367         else:
   384         else:
   368             kwargs['rql'] = 'Any X WHERE X eid %s' % self.eid
   385             kwargs['rql'] = 'Any X WHERE X eid %s' % self.eid
   369         return self.build_url(method, **kwargs)
   386         return self.build_url(method, **kwargs)
   370 
   387 
   371     def rest_path(self):
   388     def rest_path(self, use_ext_eid=False):
   372         """returns a REST-like (relative) path for this entity"""
   389         """returns a REST-like (relative) path for this entity"""
   373         mainattr, needcheck = self._rest_attr_info()
   390         mainattr, needcheck = self._rest_attr_info()
   374         etype = str(self.e_schema)
   391         etype = str(self.e_schema)
   375         if mainattr == 'eid':
   392         path = etype.lower()
   376             value = self.eid
   393         if mainattr != 'eid':
   377         else:
       
   378             value = getattr(self, mainattr)
   394             value = getattr(self, mainattr)
   379             if value is None:
   395             if value is None:
   380                 return '%s/eid/%s' % (etype.lower(), self.eid)
   396                 mainattr = 'eid'
   381         if needcheck:
   397                 path += '/eid'
   382             # make sure url is not ambiguous
   398             elif needcheck:
   383             rql = 'Any COUNT(X) WHERE X is %s, X %s %%(value)s' % (etype, mainattr)
   399                 # make sure url is not ambiguous
   384             if value is not None:
   400                 rql = 'Any COUNT(X) WHERE X is %s, X %s %%(value)s' % (
   385                 nbresults = self.req.execute(rql, {'value' : value})[0][0]
   401                     etype, mainattr)
   386                 # may an assertion that nbresults is not 0 would be a good idea
   402                 if value is not None:
   387                 if nbresults != 1: # no ambiguity
   403                     nbresults = self.req.execute(rql, {'value' : value})[0][0]
   388                     return '%s/eid/%s' % (etype.lower(), self.eid)
   404                     if nbresults != 1: # ambiguity?
   389         return '%s/%s' % (etype.lower(), self.req.url_quote(value))
   405                         mainattr = 'eid'
   390 
   406                         path += '/eid'
   391     @classmethod
       
   392     def _rest_attr_info(cls):
       
   393         mainattr, needcheck = 'eid', True
       
   394         if cls.rest_attr:
       
   395             mainattr = cls.rest_attr
       
   396             needcheck = not cls.e_schema.has_unique_values(mainattr)
       
   397         else:
       
   398             for rschema in cls.e_schema.subject_relations():
       
   399                 if rschema.is_final() and rschema != 'eid' and cls.e_schema.has_unique_values(rschema):
       
   400                     mainattr = str(rschema)
       
   401                     needcheck = False
       
   402                     break
       
   403         if mainattr == 'eid':
   407         if mainattr == 'eid':
   404             needcheck = False
   408             if use_ext_eid:
   405         return mainattr, needcheck
   409                 value = self.metainformation()['extid']
       
   410             else:
       
   411                 value = self.eid
       
   412         return '%s/%s' % (path, self.req.url_quote(value))
   406 
   413 
   407     def attr_metadata(self, attr, metadata):
   414     def attr_metadata(self, attr, metadata):
   408         """return a metadata for an attribute (None if unspecified)"""
   415         """return a metadata for an attribute (None if unspecified)"""
   409         value = getattr(self, '%s_%s' % (attr, metadata), None)
   416         value = getattr(self, '%s_%s' % (attr, metadata), None)
   410         if value is None and metadata == 'encoding':
   417         if value is None and metadata == 'encoding':