cubicweb/entity.py
changeset 12508 a8c1ea390400
parent 11891 67185e65f020
child 12542 85194bd49119
equal deleted inserted replaced
12507:211472ab15c8 12508:a8c1ea390400
    21 
    21 
    22 from six import text_type, string_types, integer_types
    22 from six import text_type, string_types, integer_types
    23 from six.moves import range
    23 from six.moves import range
    24 
    24 
    25 from logilab.common.decorators import cached
    25 from logilab.common.decorators import cached
    26 from logilab.common.deprecation import deprecated
       
    27 from logilab.common.registry import yes
    26 from logilab.common.registry import yes
    28 from logilab.mtconverter import TransformData, xml_escape
    27 from logilab.mtconverter import TransformData, xml_escape
    29 
    28 
    30 from rql.utils import rqlvar_maker
    29 from rql.utils import rqlvar_maker
    31 from rql.stmts import Select
    30 from rql.stmts import Select
   173     __select__ = yes()
   172     __select__ = yes()
   174 
   173 
   175     # class attributes that must be set in class definition
   174     # class attributes that must be set in class definition
   176     rest_attr = None
   175     rest_attr = None
   177     fetch_attrs = None
   176     fetch_attrs = None
   178     skip_copy_for = () # bw compat (< 3.14), use cw_skip_copy_for instead
       
   179     cw_skip_copy_for = [('in_state', 'subject')]
   177     cw_skip_copy_for = [('in_state', 'subject')]
   180     # class attributes set automatically at registration time
   178     # class attributes set automatically at registration time
   181     e_schema = None
   179     e_schema = None
   182 
   180 
   183     @classmethod
   181     @classmethod
   254         """
   252         """
   255         if attr == 'modification_date':
   253         if attr == 'modification_date':
   256             select.add_sort_var(var, asc=False)
   254             select.add_sort_var(var, asc=False)
   257 
   255 
   258     @classmethod
   256     @classmethod
   259     def fetch_rql(cls, user, restriction=None, fetchattrs=None, mainvar='X',
   257     def fetch_rql(cls, user, fetchattrs=None, mainvar='X',
   260                   settype=True, ordermethod='fetch_order'):
   258                   settype=True, ordermethod='fetch_order'):
   261         st = cls.fetch_rqlst(user, mainvar=mainvar, fetchattrs=fetchattrs,
   259         st = cls.fetch_rqlst(user, mainvar=mainvar, fetchattrs=fetchattrs,
   262                              settype=settype, ordermethod=ordermethod)
   260                              settype=settype, ordermethod=ordermethod)
   263         rql = st.as_string()
   261         return st.as_string()
   264         if restriction:
       
   265             # cannot use RQLRewriter API to insert 'X rtype %(x)s' restriction
       
   266             warn('[3.14] fetch_rql: use of `restriction` parameter is '
       
   267                  'deprecated, please use fetch_rqlst and supply a syntax'
       
   268                  'tree with your restriction instead', DeprecationWarning)
       
   269             insert = ' WHERE ' + ','.join(restriction)
       
   270             if ' WHERE ' in rql:
       
   271                 select, where = rql.split(' WHERE ', 1)
       
   272                 rql = select + insert + ',' + where
       
   273             else:
       
   274                 rql += insert
       
   275         return rql
       
   276 
   262 
   277     @classmethod
   263     @classmethod
   278     def fetch_rqlst(cls, user, select=None, mainvar='X', fetchattrs=None,
   264     def fetch_rqlst(cls, user, select=None, mainvar='X', fetchattrs=None,
   279                     settype=True, ordermethod='fetch_order'):
   265                     settype=True, ordermethod='fetch_order'):
   280         if select is None:
   266         if select is None:
   620         'before_add_entity' hooks). You can use this method to ensure the entity
   606         'before_add_entity' hooks). You can use this method to ensure the entity
   621         has an eid *and* is saved in its source.
   607         has an eid *and* is saved in its source.
   622         """
   608         """
   623         return self.has_eid() and self._cw_is_saved
   609         return self.has_eid() and self._cw_is_saved
   624 
   610 
   625     @deprecated('[3.24] cw_metainformation is deprecated')
       
   626     @cached
       
   627     def cw_metainformation(self):
       
   628         source = self.cw_source[0].name
       
   629         return {'type': self.cw_etype,
       
   630                 'extid': self.cwuri if source != 'system' else None,
       
   631                 'source': {'uri': source}}
       
   632 
       
   633     def cw_check_perm(self, action):
   611     def cw_check_perm(self, action):
   634         self.e_schema.check_perm(self._cw, action, eid=self.eid)
   612         self.e_schema.check_perm(self._cw, action, eid=self.eid)
   635 
   613 
   636     def cw_has_perm(self, action):
   614     def cw_has_perm(self, action):
   637         return self.e_schema.has_perm(self._cw, action, eid=self.eid)
   615         return self.e_schema.has_perm(self._cw, action, eid=self.eid)
   757         Overrides this if you want another behaviour
   735         Overrides this if you want another behaviour
   758         """
   736         """
   759         assert self.has_eid()
   737         assert self.has_eid()
   760         execute = self._cw.execute
   738         execute = self._cw.execute
   761         skip_copy_for = {'subject': set(), 'object': set()}
   739         skip_copy_for = {'subject': set(), 'object': set()}
   762         for rtype in self.skip_copy_for:
       
   763             skip_copy_for['subject'].add(rtype)
       
   764             warn('[3.14] skip_copy_for on entity classes (%s) is deprecated, '
       
   765                  'use cw_skip_copy_for instead with list of couples (rtype, role)' % self.cw_etype,
       
   766                  DeprecationWarning)
       
   767         for rtype, role in self.cw_skip_copy_for:
   740         for rtype, role in self.cw_skip_copy_for:
   768             assert role in ('subject', 'object'), role
   741             assert role in ('subject', 'object'), role
   769             skip_copy_for[role].add(rtype)
   742             skip_copy_for[role].add(rtype)
   770         for rschema in self.e_schema.subject_relations():
   743         for rschema in self.e_schema.subject_relations():
   771             if rschema.type in skip_copy_for['subject']:
   744             if rschema.type in skip_copy_for['subject']:
  1341 
  1314 
  1342     def _cw_clear_local_perm_cache(self, action):
  1315     def _cw_clear_local_perm_cache(self, action):
  1343         for rqlexpr in self.e_schema.get_rqlexprs(action):
  1316         for rqlexpr in self.e_schema.get_rqlexprs(action):
  1344             self._cw.local_perm_cache.pop((rqlexpr.eid, (('x', self.eid),)), None)
  1317             self._cw.local_perm_cache.pop((rqlexpr.eid, (('x', self.eid),)), None)
  1345 
  1318 
  1346     # deprecated stuff #########################################################
       
  1347 
       
  1348     @deprecated('[3.16] use cw_set() instead of set_attributes()')
       
  1349     def set_attributes(self, **kwargs): # XXX cw_set_attributes
       
  1350         if kwargs:
       
  1351             self.cw_set(**kwargs)
       
  1352 
       
  1353     @deprecated('[3.16] use cw_set() instead of set_relations()')
       
  1354     def set_relations(self, **kwargs): # XXX cw_set_relations
       
  1355         """add relations to the given object. To set a relation where this entity
       
  1356         is the object of the relation, use 'reverse_'<relation> as argument name.
       
  1357 
       
  1358         Values may be an entity or eid, a list of entities or eids, or None
       
  1359         (meaning that all relations of the given type from or to this object
       
  1360         should be deleted).
       
  1361         """
       
  1362         if kwargs:
       
  1363             self.cw_set(**kwargs)
       
  1364 
       
  1365     @deprecated('[3.13] use entity.cw_clear_all_caches()')
       
  1366     def clear_all_caches(self):
       
  1367         return self.cw_clear_all_caches()
       
  1368 
       
  1369 
  1319 
  1370 # attribute and relation descriptors ##########################################
  1320 # attribute and relation descriptors ##########################################
  1371 
  1321 
  1372 class Attribute(object):
  1322 class Attribute(object):
  1373     """descriptor that controls schema attribute access"""
  1323     """descriptor that controls schema attribute access"""
  1378 
  1328 
  1379     def __get__(self, eobj, eclass):
  1329     def __get__(self, eobj, eclass):
  1380         if eobj is None:
  1330         if eobj is None:
  1381             return self
  1331             return self
  1382         return eobj.cw_attr_value(self._attrname)
  1332         return eobj.cw_attr_value(self._attrname)
  1383 
       
  1384     @deprecated('[3.10] assign to entity.cw_attr_cache[attr] or entity.cw_edited[attr]')
       
  1385     def __set__(self, eobj, value):
       
  1386         if hasattr(eobj, 'cw_edited') and not eobj.cw_edited.saved:
       
  1387             eobj.cw_edited[self._attrname] = value
       
  1388         else:
       
  1389             eobj.cw_attr_cache[self._attrname] = value
       
  1390 
  1333 
  1391 
  1334 
  1392 class Relation(object):
  1335 class Relation(object):
  1393     """descriptor that controls schema relation access"""
  1336     """descriptor that controls schema relation access"""
  1394 
  1337