server/hooks.py
branchstable
changeset 2101 08003e0354a7
parent 1977 606923dff11b
child 2195 58bef4f707ce
equal deleted inserted replaced
2100:89b825cdec74 2101:08003e0354a7
    16 from cubicweb.server.hookhelper import (check_internal_entity, previous_state,
    16 from cubicweb.server.hookhelper import (check_internal_entity, previous_state,
    17                                      get_user_sessions, rproperty)
    17                                      get_user_sessions, rproperty)
    18 from cubicweb.server.repository import FTIndexEntityOp
    18 from cubicweb.server.repository import FTIndexEntityOp
    19 
    19 
    20 def relation_deleted(session, eidfrom, rtype, eidto):
    20 def relation_deleted(session, eidfrom, rtype, eidto):
    21     session.add_query_data('pendingrelations', (eidfrom, rtype, eidto))
    21     session.transaction_data.setdefault('pendingrelations', []).append(
       
    22         (eidfrom, rtype, eidto))
    22 
    23 
    23 
    24 
    24 # base meta-data handling #####################################################
    25 # base meta-data handling #####################################################
    25 
    26 
    26 def setctime_before_add_entity(session, entity):
    27 def setctime_before_add_entity(session, entity):
    39         entity['modification_date'] = datetime.now()
    40         entity['modification_date'] = datetime.now()
    40 
    41 
    41 class SetCreatorOp(PreCommitOperation):
    42 class SetCreatorOp(PreCommitOperation):
    42 
    43 
    43     def precommit_event(self):
    44     def precommit_event(self):
    44         if self.eid in self.session.query_data('pendingeids', ()):
    45         if self.eid in self.session.transaction_data.get('pendingeids', ()):
    45             # entity have been created and deleted in the same transaction
    46             # entity have been created and deleted in the same transaction
    46             return
    47             return
    47         ueid = self.session.user.eid
    48         ueid = self.session.user.eid
    48         execute = self.session.unsafe_execute
    49         execute = self.session.unsafe_execute
    49         if not execute('Any X WHERE X created_by U, X eid %(x)s',
    50         if not execute('Any X WHERE X created_by U, X eid %(x)s',
   136     has actually been redirected to another composite
   137     has actually been redirected to another composite
   137     """
   138     """
   138 
   139 
   139     def precommit_event(self):
   140     def precommit_event(self):
   140         session = self.session
   141         session = self.session
   141         if not self.eid in session.query_data('pendingeids', ()):
   142         if not self.eid in session.transaction_data.get('pendingeids', ()):
   142             etype = session.describe(self.eid)[0]
   143             etype = session.describe(self.eid)[0]
   143             session.unsafe_execute('DELETE %s X WHERE X eid %%(x)s, NOT %s'
   144             session.unsafe_execute('DELETE %s X WHERE X eid %%(x)s, NOT %s'
   144                                    % (etype, self.relation),
   145                                    % (etype, self.relation),
   145                                    {'x': self.eid}, 'x')
   146                                    {'x': self.eid}, 'x')
   146 
   147 
   164     """
   165     """
   165     def precommit_event(self):
   166     def precommit_event(self):
   166         eidfrom, rtype, eidto = self.rdef
   167         eidfrom, rtype, eidto = self.rdef
   167         # first check related entities have not been deleted in the same
   168         # first check related entities have not been deleted in the same
   168         # transaction
   169         # transaction
   169         pending = self.session.query_data('pendingeids', ())
   170         pending = self.session.transaction_data.get('pendingeids', ())
   170         if eidfrom in pending:
   171         if eidfrom in pending:
   171             return
   172             return
   172         if eidto in pending:
   173         if eidto in pending:
   173             return
   174             return
   174         for constraint in self.constraints:
   175         for constraint in self.constraints:
   215     """
   216     """
   216     eid, rtype = None, None
   217     eid, rtype = None, None
   217 
   218 
   218     def precommit_event(self):
   219     def precommit_event(self):
   219         # recheck pending eids
   220         # recheck pending eids
   220         if self.eid in self.session.query_data('pendingeids', ()):
   221         if self.eid in self.session.transaction_data.get('pendingeids', ()):
   221             return
   222             return
   222         if self.session.unsafe_execute(*self._rql()).rowcount < 1:
   223         if self.session.unsafe_execute(*self._rql()).rowcount < 1:
   223             etype = self.session.describe(self.eid)[0]
   224             etype = self.session.describe(self.eid)[0]
   224             msg = self.session._('at least one relation %(rtype)s is required on %(etype)s (%(eid)s)')
   225             msg = self.session._('at least one relation %(rtype)s is required on %(etype)s (%(eid)s)')
   225             raise ValidationError(self.eid, {self.rtype: msg % {'rtype': self.rtype,
   226             raise ValidationError(self.eid, {self.rtype: msg % {'rtype': self.rtype,
   272             checkrel_if_necessary(session, opcls, rschema.type, eid)
   273             checkrel_if_necessary(session, opcls, rschema.type, eid)
   273 
   274 
   274 def cardinalitycheck_before_del_relation(session, eidfrom, rtype, eidto):
   275 def cardinalitycheck_before_del_relation(session, eidfrom, rtype, eidto):
   275     """check cardinalities are satisfied"""
   276     """check cardinalities are satisfied"""
   276     card = rproperty(session, rtype, eidfrom, eidto, 'cardinality')
   277     card = rproperty(session, rtype, eidfrom, eidto, 'cardinality')
   277     pendingeids = session.query_data('pendingeids', ())
   278     pendingeids = session.transaction_data.get('pendingeids', ())
   278     if card[0] in '1+' and not eidfrom in pendingeids:
   279     if card[0] in '1+' and not eidfrom in pendingeids:
   279         checkrel_if_necessary(session, CheckSRelationOp, rtype, eidfrom)
   280         checkrel_if_necessary(session, CheckSRelationOp, rtype, eidfrom)
   280     if card[1] in '1+' and not eidto in pendingeids:
   281     if card[1] in '1+' and not eidto in pendingeids:
   281         checkrel_if_necessary(session, CheckORelationOp, rtype, eidto)
   282         checkrel_if_necessary(session, CheckORelationOp, rtype, eidto)
   282 
   283 
   421         entity = self.entity
   422         entity = self.entity
   422         rset = session.execute('Any S WHERE ET initial_state S, ET name %(name)s',
   423         rset = session.execute('Any S WHERE ET initial_state S, ET name %(name)s',
   423                                {'name': str(entity.e_schema)})
   424                                {'name': str(entity.e_schema)})
   424         # if there is an initial state and the entity's state is not set,
   425         # if there is an initial state and the entity's state is not set,
   425         # use the initial state as a default state
   426         # use the initial state as a default state
   426         pendingeids = session.query_data('pendingeids', ())
   427         pendingeids = session.transaction_data.get('pendingeids', ())
   427         if rset and not entity.eid in pendingeids and not entity.in_state:
   428         if rset and not entity.eid in pendingeids and not entity.in_state:
   428             session.unsafe_execute('SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
   429             session.unsafe_execute('SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
   429                                    {'x' : entity.eid, 's' : rset[0][0]}, 'x')
   430                                    {'x' : entity.eid, 's' : rset[0][0]}, 'x')
   430 
   431 
   431 
   432 
   503         # site wide properties
   504         # site wide properties
   504         ChangeCWPropertyOp(session, epropdict=session.vreg.eprop_values,
   505         ChangeCWPropertyOp(session, epropdict=session.vreg.eprop_values,
   505                           key=key, value=value)
   506                           key=key, value=value)
   506 
   507 
   507 def before_del_eproperty(session, eid):
   508 def before_del_eproperty(session, eid):
   508     for eidfrom, rtype, eidto in session.query_data('pendingrelations', ()):
   509     for eidfrom, rtype, eidto in session.transaction_data.get('pendingrelations', ()):
   509         if rtype == 'for_user' and eidfrom == eid:
   510         if rtype == 'for_user' and eidfrom == eid:
   510             # if for_user was set, delete has already been handled
   511             # if for_user was set, delete has already been handled
   511             break
   512             break
   512     else:
   513     else:
   513         key = session.execute('Any K WHERE P eid %(x)s, P pkey K',
   514         key = session.execute('Any K WHERE P eid %(x)s, P pkey K',