58 # the check for ?, /, & are to prevent problems when running |
58 # the check for ?, /, & are to prevent problems when running |
59 # behind Apache mod_proxy |
59 # behind Apache mod_proxy |
60 if value == u'' or u'?' in value or u'/' in value or u'&' in value: |
60 if value == u'' or u'?' in value or u'/' in value or u'&' in value: |
61 return False |
61 return False |
62 return True |
62 return True |
|
63 |
|
64 |
|
65 def remove_ambiguous_rels(attr_set, subjtypes, schema): |
|
66 '''remove from `attr_set` the relations of entity types `subjtypes` that have |
|
67 different entity type sets as target''' |
|
68 for attr in attr_set.copy(): |
|
69 rschema = schema.rschema(attr) |
|
70 if rschema.final: |
|
71 continue |
|
72 ttypes = None |
|
73 for subjtype in subjtypes: |
|
74 cur_ttypes = rschema.objects(subjtype) |
|
75 if ttypes is None: |
|
76 ttypes = cur_ttypes |
|
77 elif cur_ttypes != ttypes: |
|
78 attr_set.remove(attr) |
|
79 break |
63 |
80 |
64 |
81 |
65 class Entity(AppObject): |
82 class Entity(AppObject): |
66 """an entity instance has e_schema automagically set on |
83 """an entity instance has e_schema automagically set on |
67 the class and instances has access to their issuing cursor. |
84 the class and instances has access to their issuing cursor. |
220 # XXX user._cw.vreg iiiirk |
237 # XXX user._cw.vreg iiiirk |
221 etypecls = user._cw.vreg['etypes'].etype_class(targettypes[0]) |
238 etypecls = user._cw.vreg['etypes'].etype_class(targettypes[0]) |
222 if len(targettypes) > 1: |
239 if len(targettypes) > 1: |
223 # find fetch_attrs common to all destination types |
240 # find fetch_attrs common to all destination types |
224 fetchattrs = user._cw.vreg['etypes'].fetch_attrs(targettypes) |
241 fetchattrs = user._cw.vreg['etypes'].fetch_attrs(targettypes) |
|
242 remove_ambiguous_rels(fetchattrs, targettypes, user._cw.vreg.schema) |
225 else: |
243 else: |
226 fetchattrs = etypecls.fetch_attrs |
244 fetchattrs = etypecls.fetch_attrs |
227 etypecls._fetch_restrictions(var, varmaker, fetchattrs, |
245 etypecls._fetch_restrictions(var, varmaker, fetchattrs, |
228 selection, orderby, restrictions, |
246 selection, orderby, restrictions, |
229 user, ordermethod, visited=visited) |
247 user, ordermethod, visited=visited) |
737 restriction += ', X is IN (%s)' % ','.join(targettypes) |
755 restriction += ', X is IN (%s)' % ','.join(targettypes) |
738 card = greater_card(rschema, targettypes, (self.e_schema,), 1) |
756 card = greater_card(rschema, targettypes, (self.e_schema,), 1) |
739 etypecls = self._cw.vreg['etypes'].etype_class(targettypes[0]) |
757 etypecls = self._cw.vreg['etypes'].etype_class(targettypes[0]) |
740 if len(targettypes) > 1: |
758 if len(targettypes) > 1: |
741 fetchattrs = self._cw.vreg['etypes'].fetch_attrs(targettypes) |
759 fetchattrs = self._cw.vreg['etypes'].fetch_attrs(targettypes) |
|
760 # XXX we should fetch ambiguous relation objects too but not |
|
761 # recurse on them in _fetch_restrictions; it is easier to remove |
|
762 # them completely for now, as it would require an deeper api rewrite |
|
763 remove_ambiguous_rels(fetchattrs, targettypes, self._cw.vreg.schema) |
742 else: |
764 else: |
743 fetchattrs = etypecls.fetch_attrs |
765 fetchattrs = etypecls.fetch_attrs |
744 rql = etypecls.fetch_rql(self._cw.user, [restriction], fetchattrs, |
766 rql = etypecls.fetch_rql(self._cw.user, [restriction], fetchattrs, |
745 settype=False) |
767 settype=False) |
746 # optimisation: remove ORDERBY if cardinality is 1 or ? (though |
768 # optimisation: remove ORDERBY if cardinality is 1 or ? (though |