16 from logilab.mtconverter import TransformData, TransformError, xml_escape |
16 from logilab.mtconverter import TransformData, TransformError, xml_escape |
17 |
17 |
18 from rql import parse |
18 from rql import parse |
19 from rql.utils import rqlvar_maker |
19 from rql.utils import rqlvar_maker |
20 |
20 |
21 from cubicweb import Unauthorized |
21 from cubicweb import Unauthorized, typed_eid |
22 from cubicweb.rset import ResultSet |
22 from cubicweb.rset import ResultSet |
23 from cubicweb.selectors import yes |
23 from cubicweb.selectors import yes |
24 from cubicweb.appobject import AppObject |
24 from cubicweb.appobject import AppObject |
25 from cubicweb.schema import RQLVocabularyConstraint, RQLConstraint |
25 from cubicweb.schema import RQLVocabularyConstraint, RQLConstraint |
26 from cubicweb.rqlrewrite import RQLRewriter |
26 from cubicweb.rqlrewrite import RQLRewriter |
585 return self.related(rtype, role, limit, entities) |
585 return self.related(rtype, role, limit, entities) |
586 |
586 |
587 def related_rql(self, rtype, role='subject', targettypes=None): |
587 def related_rql(self, rtype, role='subject', targettypes=None): |
588 rschema = self._cw.vreg.schema[rtype] |
588 rschema = self._cw.vreg.schema[rtype] |
589 if role == 'subject': |
589 if role == 'subject': |
|
590 restriction = 'E eid %%(x)s, E %s X' % rtype |
590 if targettypes is None: |
591 if targettypes is None: |
591 targettypes = rschema.objects(self.e_schema) |
592 targettypes = rschema.objects(self.e_schema) |
592 restriction = 'E eid %%(x)s, E %s X' % rtype |
593 else: |
|
594 restriction += 'E is IN (%s)' % ','.join(targettypes) |
593 card = greater_card(rschema, (self.e_schema,), targettypes, 0) |
595 card = greater_card(rschema, (self.e_schema,), targettypes, 0) |
594 else: |
596 else: |
|
597 restriction = 'E eid %%(x)s, X %s E' % rtype |
595 if targettypes is None: |
598 if targettypes is None: |
596 targettypes = rschema.subjects(self.e_schema) |
599 targettypes = rschema.subjects(self.e_schema) |
597 restriction = 'E eid %%(x)s, X %s E' % rtype |
600 else: |
|
601 restriction += 'E is IN (%s)' % ','.join(targettypes) |
598 card = greater_card(rschema, targettypes, (self.e_schema,), 1) |
602 card = greater_card(rschema, targettypes, (self.e_schema,), 1) |
599 if len(targettypes) > 1: |
603 if len(targettypes) > 1: |
600 fetchattrs_list = [] |
604 fetchattrs_list = [] |
601 for ttype in targettypes: |
605 for ttype in targettypes: |
602 etypecls = self._cw.vreg['etypes'].etype_class(ttype) |
606 etypecls = self._cw.vreg['etypes'].etype_class(ttype) |
739 else: |
743 else: |
740 assert role |
744 assert role |
741 self._related_cache.pop('%s_%s' % (rtype, role), None) |
745 self._related_cache.pop('%s_%s' % (rtype, role), None) |
742 |
746 |
743 def clear_all_caches(self): |
747 def clear_all_caches(self): |
|
748 haseid = 'eid' in self |
744 self.clear() |
749 self.clear() |
745 for rschema, _, role in self.e_schema.relation_definitions(): |
750 for rschema, _, role in self.e_schema.relation_definitions(): |
746 self.clear_related_cache(rschema.type, role) |
751 self.clear_related_cache(rschema.type, role) |
|
752 # set eid if it was in, else we may get nasty error while editing this |
|
753 # entity if it's bound to a repo session |
|
754 if haseid: |
|
755 self['eid'] = self.eid |
747 |
756 |
748 # raw edition utilities ################################################### |
757 # raw edition utilities ################################################### |
749 |
758 |
750 def set_attributes(self, _cw_unsafe=False, **kwargs): |
759 def set_attributes(self, _cw_unsafe=False, **kwargs): |
751 assert kwargs |
760 assert kwargs |
760 self._cw.unsafe_execute( |
769 self._cw.unsafe_execute( |
761 'SET %s WHERE X eid %%(x)s' % ','.join(relations), kwargs, 'x') |
770 'SET %s WHERE X eid %%(x)s' % ','.join(relations), kwargs, 'x') |
762 else: |
771 else: |
763 self._cw.execute('SET %s WHERE X eid %%(x)s' % ','.join(relations), |
772 self._cw.execute('SET %s WHERE X eid %%(x)s' % ','.join(relations), |
764 kwargs, 'x') |
773 kwargs, 'x') |
|
774 |
|
775 def set_relations(self, _cw_unsafe=False, **kwargs): |
|
776 if _cw_unsafe: |
|
777 execute = self.req.unsafe_execute |
|
778 else: |
|
779 execute = self.req.execute |
|
780 for attr, values in kwargs.iteritems(): |
|
781 if attr.startswith('reverse_'): |
|
782 restr = 'Y %s X' % attr[len('reverse_'):] |
|
783 else: |
|
784 restr = 'X %s Y' % attr |
|
785 execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % ( |
|
786 restr, ','.join(str(r.eid) for r in values)), |
|
787 {'x': self.eid}, 'x') |
765 |
788 |
766 def delete(self): |
789 def delete(self): |
767 assert self.has_eid(), self.eid |
790 assert self.has_eid(), self.eid |
768 self._cw.execute('DELETE %s X WHERE X eid %%(x)s' % self.e_schema, |
791 self._cw.execute('DELETE %s X WHERE X eid %%(x)s' % self.e_schema, |
769 {'x': self.eid}) |
792 {'x': self.eid}) |