entity.py
changeset 3674 387d51af966d
parent 3649 59eb710b9862
parent 3672 554a588ffaea
child 3720 5376aaadd16b
equal deleted inserted replaced
3661:12ea53a4c0da 3674:387d51af966d
    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
   230     def has_eid(self):
   230     def has_eid(self):
   231         """return True if the entity has an attributed eid (False
   231         """return True if the entity has an attributed eid (False
   232         meaning that the entity has to be created
   232         meaning that the entity has to be created
   233         """
   233         """
   234         try:
   234         try:
   235             int(self.eid)
   235             typed_eid(self.eid)
   236             return True
   236             return True
   237         except (ValueError, TypeError):
   237         except (ValueError, TypeError):
   238             return False
   238             return False
   239 
   239 
   240     def is_saved(self):
   240     def is_saved(self):
   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})