entity.py
changeset 3720 5376aaadd16b
parent 3674 387d51af966d
parent 3689 deb13e88e037
child 3777 3ef8cdb5fb1c
equal deleted inserted replaced
3678:29f74716fd70 3720:5376aaadd16b
   137         else:
   137         else:
   138             visited.add(eschema.type)
   138             visited.add(eschema.type)
   139         _fetchattrs = []
   139         _fetchattrs = []
   140         for attr in fetchattrs:
   140         for attr in fetchattrs:
   141             try:
   141             try:
   142                 rschema = eschema.subject_relation(attr)
   142                 rschema = eschema.subjrels[attr]
   143             except KeyError:
   143             except KeyError:
   144                 cls.warning('skipping fetch_attr %s defined in %s (not found in schema)',
   144                 cls.warning('skipping fetch_attr %s defined in %s (not found in schema)',
   145                             attr, cls.__regid__)
   145                             attr, cls.__regid__)
   146                 continue
   146                 continue
   147             if not user.matching_groups(rschema.get_groups('read')):
   147             if not user.matching_groups(rschema.get_groups('read')):
   148                 continue
   148                 continue
   149             var = varmaker.next()
   149             var = varmaker.next()
   150             selection.append(var)
   150             selection.append(var)
   151             restriction = '%s %s %s' % (mainvar, attr, var)
   151             restriction = '%s %s %s' % (mainvar, attr, var)
   152             restrictions.append(restriction)
   152             restrictions.append(restriction)
   153             if not rschema.is_final():
   153             if not rschema.final:
   154                 # XXX this does not handle several destination types
   154                 # XXX this does not handle several destination types
   155                 desttype = rschema.objects(eschema.type)[0]
   155                 desttype = rschema.objects(eschema.type)[0]
   156                 card = rschema.rproperty(eschema, desttype, 'cardinality')[0]
   156                 card = rschema.rproperty(eschema, desttype, 'cardinality')[0]
   157                 if card not in '?1':
   157                 if card not in '?1':
   158                     cls.warning('bad relation %s specified in fetch attrs for %s',
   158                     cls.warning('bad relation %s specified in fetch attrs for %s',
   182         if cls.rest_attr:
   182         if cls.rest_attr:
   183             mainattr = cls.rest_attr
   183             mainattr = cls.rest_attr
   184             needcheck = not cls.e_schema.has_unique_values(mainattr)
   184             needcheck = not cls.e_schema.has_unique_values(mainattr)
   185         else:
   185         else:
   186             for rschema in cls.e_schema.subject_relations():
   186             for rschema in cls.e_schema.subject_relations():
   187                 if rschema.is_final() and rschema != 'eid' and cls.e_schema.has_unique_values(rschema):
   187                 if rschema.final and rschema != 'eid' and cls.e_schema.has_unique_values(rschema):
   188                     mainattr = str(rschema)
   188                     mainattr = str(rschema)
   189                     needcheck = False
   189                     needcheck = False
   190                     break
   190                     break
   191         if mainattr == 'eid':
   191         if mainattr == 'eid':
   192             needcheck = False
   192             needcheck = False
   381         Overrides this if you want another behaviour
   381         Overrides this if you want another behaviour
   382         """
   382         """
   383         assert self.has_eid()
   383         assert self.has_eid()
   384         execute = self._cw.execute
   384         execute = self._cw.execute
   385         for rschema in self.e_schema.subject_relations():
   385         for rschema in self.e_schema.subject_relations():
   386             if rschema.is_final() or rschema.meta:
   386             if rschema.final or rschema.meta:
   387                 continue
   387                 continue
   388             # skip already defined relations
   388             # skip already defined relations
   389             if getattr(self, rschema.type):
   389             if getattr(self, rschema.type):
   390                 continue
   390                 continue
   391             if rschema.type in self.skip_copy_for:
   391             if rschema.type in self.skip_copy_for:
   429         return self._cw.decorate_rset(rset)
   429         return self._cw.decorate_rset(rset)
   430 
   430 
   431     def to_complete_relations(self):
   431     def to_complete_relations(self):
   432         """by default complete final relations to when calling .complete()"""
   432         """by default complete final relations to when calling .complete()"""
   433         for rschema in self.e_schema.subject_relations():
   433         for rschema in self.e_schema.subject_relations():
   434             if rschema.is_final():
   434             if rschema.final:
   435                 continue
   435                 continue
   436             if len(rschema.objects(self.e_schema)) > 1:
   436             if len(rschema.objects(self.e_schema)) > 1:
   437                 # ambigous relations, the querier doesn't handle
   437                 # ambigous relations, the querier doesn't handle
   438                 # outer join correctly in this case
   438                 # outer join correctly in this case
   439                 continue
   439                 continue
   589         if role == 'subject':
   589         if role == 'subject':
   590             restriction = 'E eid %%(x)s, E %s X' % rtype
   590             restriction = 'E eid %%(x)s, E %s X' % rtype
   591             if targettypes is None:
   591             if targettypes is None:
   592                 targettypes = rschema.objects(self.e_schema)
   592                 targettypes = rschema.objects(self.e_schema)
   593             else:
   593             else:
   594                 restriction += 'E is IN (%s)' % ','.join(targettypes)
   594                 restriction += ', X is IN (%s)' % ','.join(targettypes)
   595             card = greater_card(rschema, (self.e_schema,), targettypes, 0)
   595             card = greater_card(rschema, (self.e_schema,), targettypes, 0)
   596         else:
   596         else:
   597             restriction = 'E eid %%(x)s, X %s E' % rtype
   597             restriction = 'E eid %%(x)s, X %s E' % rtype
   598             if targettypes is None:
   598             if targettypes is None:
   599                 targettypes = rschema.subjects(self.e_schema)
   599                 targettypes = rschema.subjects(self.e_schema)
   600             else:
   600             else:
   601                 restriction += 'E is IN (%s)' % ','.join(targettypes)
   601                 restriction += ', X is IN (%s)' % ','.join(targettypes)
   602             card = greater_card(rschema, targettypes, (self.e_schema,), 1)
   602             card = greater_card(rschema, targettypes, (self.e_schema,), 1)
   603         if len(targettypes) > 1:
   603         if len(targettypes) > 1:
   604             fetchattrs_list = []
   604             fetchattrs_list = []
   605             for ttype in targettypes:
   605             for ttype in targettypes:
   606                 etypecls = self._cw.vreg['etypes'].etype_class(ttype)
   606                 etypecls = self._cw.vreg['etypes'].etype_class(ttype)
   704     def related_cache(self, rtype, role, entities=True, limit=None):
   704     def related_cache(self, rtype, role, entities=True, limit=None):
   705         """return values for the given relation if it's cached on the instance,
   705         """return values for the given relation if it's cached on the instance,
   706         else raise `KeyError`
   706         else raise `KeyError`
   707         """
   707         """
   708         res = self._related_cache['%s_%s' % (rtype, role)][entities]
   708         res = self._related_cache['%s_%s' % (rtype, role)][entities]
   709         if limit is not None:
   709         if limit is not None and limit < len(res):
   710             if entities:
   710             if entities:
   711                 res = res[:limit]
   711                 res = res[:limit]
   712             else:
   712             else:
   713                 res = res.limit(limit)
   713                 res = res.limit(limit)
   714         return res
   714         return res