638 """by default complete final relations to when calling .complete()""" |
638 """by default complete final relations to when calling .complete()""" |
639 for rschema in self.e_schema.subject_relations(): |
639 for rschema in self.e_schema.subject_relations(): |
640 if rschema.final: |
640 if rschema.final: |
641 continue |
641 continue |
642 targets = rschema.objects(self.e_schema) |
642 targets = rschema.objects(self.e_schema) |
643 if len(targets) > 1: |
|
644 # ambigous relations, the querier doesn't handle |
|
645 # outer join correctly in this case |
|
646 continue |
|
647 if rschema.inlined: |
643 if rschema.inlined: |
648 matching_groups = self._cw.user.matching_groups |
644 matching_groups = self._cw.user.matching_groups |
649 rdef = rschema.rdef(self.e_schema, targets[0]) |
645 if all(matching_groups(e.get_groups('read')) and |
650 if matching_groups(rdef.get_groups('read')) and \ |
646 rschema.rdef(self.e_schema, e).get_groups('read') |
651 all(matching_groups(e.get_groups('read')) for e in targets): |
647 for e in targets): |
652 yield rschema, 'subject' |
648 yield rschema, 'subject' |
653 |
649 |
654 def _cw_to_complete_attributes(self, skip_bytes=True, skip_pwd=True): |
650 def _cw_to_complete_attributes(self, skip_bytes=True, skip_pwd=True): |
655 for rschema, attrschema in self.e_schema.attribute_definitions(): |
651 for rschema, attrschema in self.e_schema.attribute_definitions(): |
656 # skip binary data by default |
652 # skip binary data by default |
699 # fetch additional relations (restricted to 0..1 relations) |
695 # fetch additional relations (restricted to 0..1 relations) |
700 for rschema, role in self._cw_to_complete_relations(): |
696 for rschema, role in self._cw_to_complete_relations(): |
701 rtype = rschema.type |
697 rtype = rschema.type |
702 if self.cw_relation_cached(rtype, role): |
698 if self.cw_relation_cached(rtype, role): |
703 continue |
699 continue |
|
700 # at this point we suppose that: |
|
701 # * this is a inlined relation |
|
702 # * entity (self) is the subject |
|
703 # * user has read perm on the relation and on the target entity |
|
704 assert rschema.inlined |
|
705 assert role == 'subject' |
704 var = varmaker.next() |
706 var = varmaker.next() |
705 targettype = rschema.targets(self.e_schema, role)[0] |
707 # keep outer join anyway, we don't want .complete to crash on |
706 rdef = rschema.role_rdef(self.e_schema, targettype, role) |
708 # missing mandatory relation (see #1058267) |
707 card = rdef.role_cardinality(role) |
709 rql.append('%s %s %s?' % (V, rtype, var)) |
708 assert card in '1?', '%s %s %s %s' % (self.e_schema, rtype, |
|
709 role, card) |
|
710 if role == 'subject': |
|
711 if card == '1': |
|
712 rql.append('%s %s %s' % (V, rtype, var)) |
|
713 else: |
|
714 rql.append('%s %s %s?' % (V, rtype, var)) |
|
715 else: |
|
716 if card == '1': |
|
717 rql.append('%s %s %s' % (var, rtype, V)) |
|
718 else: |
|
719 rql.append('%s? %s %s' % (var, rtype, V)) |
|
720 selected.append(((rtype, role), var)) |
710 selected.append(((rtype, role), var)) |
721 if selected: |
711 if selected: |
722 # select V, we need it as the left most selected variable |
712 # select V, we need it as the left most selected variable |
723 # if some outer join are included to fetch inlined relations |
713 # if some outer join are included to fetch inlined relations |
724 rql = 'Any %s,%s %s' % (V, ','.join(var for attr, var in selected), |
714 rql = 'Any %s,%s %s' % (V, ','.join(var for attr, var in selected), |