entity.py
branchstable
changeset 5425 7c84e3f370de
parent 5423 e15abfdcce38
child 5426 0d4853a6e5ee
equal deleted inserted replaced
5421:8167de96c523 5425:7c84e3f370de
   572             # object (inlined relation) or inserting some inconsistency
   572             # object (inlined relation) or inserting some inconsistency
   573             if rdef.cardinality[1] in '?1':
   573             if rdef.cardinality[1] in '?1':
   574                 continue
   574                 continue
   575             rql = 'SET X %s V WHERE X eid %%(x)s, Y eid %%(y)s, Y %s V' % (
   575             rql = 'SET X %s V WHERE X eid %%(x)s, Y eid %%(y)s, Y %s V' % (
   576                 rschema.type, rschema.type)
   576                 rschema.type, rschema.type)
   577             execute(rql, {'x': self.eid, 'y': ceid}, ('x', 'y'))
   577             execute(rql, {'x': self.eid, 'y': ceid})
   578             self.clear_related_cache(rschema.type, 'subject')
   578             self.clear_related_cache(rschema.type, 'subject')
   579         for rschema in self.e_schema.object_relations():
   579         for rschema in self.e_schema.object_relations():
   580             if rschema.meta:
   580             if rschema.meta:
   581                 continue
   581                 continue
   582             # skip already defined relations
   582             # skip already defined relations
   590             # object (inlined relation) or inserting some inconsistency
   590             # object (inlined relation) or inserting some inconsistency
   591             if rdef.cardinality[0] in '?1':
   591             if rdef.cardinality[0] in '?1':
   592                 continue
   592                 continue
   593             rql = 'SET V %s X WHERE X eid %%(x)s, Y eid %%(y)s, V %s Y' % (
   593             rql = 'SET V %s X WHERE X eid %%(x)s, Y eid %%(y)s, V %s Y' % (
   594                 rschema.type, rschema.type)
   594                 rschema.type, rschema.type)
   595             execute(rql, {'x': self.eid, 'y': ceid}, ('x', 'y'))
   595             execute(rql, {'x': self.eid, 'y': ceid})
   596             self.clear_related_cache(rschema.type, 'object')
   596             self.clear_related_cache(rschema.type, 'object')
   597 
   597 
   598     # data fetching methods ###################################################
   598     # data fetching methods ###################################################
   599 
   599 
   600     @cached
   600     @cached
   692         if selected:
   692         if selected:
   693             # select V, we need it as the left most selected variable
   693             # select V, we need it as the left most selected variable
   694             # if some outer join are included to fetch inlined relations
   694             # if some outer join are included to fetch inlined relations
   695             rql = 'Any %s,%s %s' % (V, ','.join(var for attr, var in selected),
   695             rql = 'Any %s,%s %s' % (V, ','.join(var for attr, var in selected),
   696                                     ','.join(rql))
   696                                     ','.join(rql))
   697             rset = self._cw.execute(rql, {'x': self.eid}, 'x',
   697             rset = self._cw.execute(rql, {'x': self.eid}, build_descr=False)[0]
   698                                     build_descr=False)[0]
       
   699             # handle attributes
   698             # handle attributes
   700             for i in xrange(1, lastattr):
   699             for i in xrange(1, lastattr):
   701                 self[str(selected[i-1][0])] = rset[i]
   700                 self[str(selected[i-1][0])] = rset[i]
   702             # handle relations
   701             # handle relations
   703             for i in xrange(lastattr, len(rset)):
   702             for i in xrange(lastattr, len(rset)):
   722         except KeyError:
   721         except KeyError:
   723             if not self.is_saved():
   722             if not self.is_saved():
   724                 return None
   723                 return None
   725             rql = "Any A WHERE X eid %%(x)s, X %s A" % name
   724             rql = "Any A WHERE X eid %%(x)s, X %s A" % name
   726             try:
   725             try:
   727                 rset = self._cw.execute(rql, {'x': self.eid}, 'x')
   726                 rset = self._cw.execute(rql, {'x': self.eid})
   728             except Unauthorized:
   727             except Unauthorized:
   729                 self[name] = value = None
   728                 self[name] = value = None
   730             else:
   729             else:
   731                 assert rset.rowcount <= 1, (self, rql, rset.rowcount)
   730                 assert rset.rowcount <= 1, (self, rql, rset.rowcount)
   732                 try:
   731                 try:
   753             return self.related_cache(rtype, role, entities, limit)
   752             return self.related_cache(rtype, role, entities, limit)
   754         except KeyError:
   753         except KeyError:
   755             pass
   754             pass
   756         assert self.has_eid()
   755         assert self.has_eid()
   757         rql = self.related_rql(rtype, role)
   756         rql = self.related_rql(rtype, role)
   758         rset = self._cw.execute(rql, {'x': self.eid}, 'x')
   757         rset = self._cw.execute(rql, {'x': self.eid})
   759         self.set_related_cache(rtype, role, rset)
   758         self.set_related_cache(rtype, role, rset)
   760         return self.related(rtype, role, limit, entities)
   759         return self.related(rtype, role, limit, entities)
   761 
   760 
   762     def related_rql(self, rtype, role='subject', targettypes=None):
   761     def related_rql(self, rtype, role='subject', targettypes=None):
   763         rschema = self._cw.vreg.schema[rtype]
   762         rschema = self._cw.vreg.schema[rtype]
   879         except Unauthorized:
   878         except Unauthorized:
   880             return self._cw.empty_rset()
   879             return self._cw.empty_rset()
   881         if limit is not None:
   880         if limit is not None:
   882             before, after = rql.split(' WHERE ', 1)
   881             before, after = rql.split(' WHERE ', 1)
   883             rql = '%s LIMIT %s WHERE %s' % (before, limit, after)
   882             rql = '%s LIMIT %s WHERE %s' % (before, limit, after)
   884         return self._cw.execute(rql, args, tuple(args))
   883         return self._cw.execute(rql, args)
   885 
   884 
   886     # relations cache handling ################################################
   885     # relations cache handling ################################################
   887 
   886 
   888     def relation_cached(self, rtype, role):
   887     def relation_cached(self, rtype, role):
   889         """return true if the given relation is already cached on the instance
   888         """return true if the given relation is already cached on the instance
   962         for key in kwargs:
   961         for key in kwargs:
   963             relations.append('X %s %%(%s)s' % (key, key))
   962             relations.append('X %s %%(%s)s' % (key, key))
   964         # and now update the database
   963         # and now update the database
   965         kwargs['x'] = self.eid
   964         kwargs['x'] = self.eid
   966         self._cw.execute('SET %s WHERE X eid %%(x)s' % ','.join(relations),
   965         self._cw.execute('SET %s WHERE X eid %%(x)s' % ','.join(relations),
   967                          kwargs, 'x')
   966                          kwargs)
   968         kwargs.pop('x')
   967         kwargs.pop('x')
   969         # update current local object _after_ the rql query to avoid
   968         # update current local object _after_ the rql query to avoid
   970         # interferences between the query execution itself and the
   969         # interferences between the query execution itself and the
   971         # edited_attributes / skip_security_attributes machinery
   970         # edited_attributes / skip_security_attributes machinery
   972         self.update(kwargs)
   971         self.update(kwargs)
   985                 restr = 'Y %s X' % attr[len('reverse_'):]
   984                 restr = 'Y %s X' % attr[len('reverse_'):]
   986             else:
   985             else:
   987                 restr = 'X %s Y' % attr
   986                 restr = 'X %s Y' % attr
   988             if values is None:
   987             if values is None:
   989                 self._cw.execute('DELETE %s WHERE X eid %%(x)s' % restr,
   988                 self._cw.execute('DELETE %s WHERE X eid %%(x)s' % restr,
   990                                  {'x': self.eid}, 'x')
   989                                  {'x': self.eid})
   991                 continue
   990                 continue
   992             if not isinstance(values, (tuple, list, set, frozenset)):
   991             if not isinstance(values, (tuple, list, set, frozenset)):
   993                 values = (values,)
   992                 values = (values,)
   994             self._cw.execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % (
   993             self._cw.execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % (
   995                 restr, ','.join(str(r.eid) for r in values)),
   994                 restr, ','.join(str(r.eid) for r in values)),
   996                              {'x': self.eid}, 'x')
   995                              {'x': self.eid})
   997 
   996 
   998     def delete(self, **kwargs):
   997     def delete(self, **kwargs):
   999         assert self.has_eid(), self.eid
   998         assert self.has_eid(), self.eid
  1000         self._cw.execute('DELETE %s X WHERE X eid %%(x)s' % self.e_schema,
   999         self._cw.execute('DELETE %s X WHERE X eid %%(x)s' % self.e_schema,
  1001                          {'x': self.eid}, **kwargs)
  1000                          {'x': self.eid}, **kwargs)