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 |