web/views/editcontroller.py
changeset 11064 113e9da47afc
parent 11063 de20b0903d7d
child 11066 dcbb64d3a1d9
equal deleted inserted replaced
11063:de20b0903d7d 11064:113e9da47afc
    73 class RqlQuery(object):
    73 class RqlQuery(object):
    74     def __init__(self):
    74     def __init__(self):
    75         self.edited = []
    75         self.edited = []
    76         self.restrictions = []
    76         self.restrictions = []
    77         self.kwargs = {}
    77         self.kwargs = {}
       
    78         self.canceled = False
    78 
    79 
    79     def __repr__(self):
    80     def __repr__(self):
    80         return ('Query <edited=%r restrictions=%r kwargs=%r>' % (
    81         return ('Query <edited=%r restrictions=%r kwargs=%r>' % (
    81             self.edited, self.restrictions, self.kwargs))
    82             self.edited, self.restrictions, self.kwargs))
    82 
    83 
    83     def insert_query(self, etype):
    84     def insert_query(self, etype):
       
    85         assert not self.canceled
    84         if self.edited:
    86         if self.edited:
    85             rql = 'INSERT %s X: %s' % (etype, ','.join(self.edited))
    87             rql = 'INSERT %s X: %s' % (etype, ','.join(self.edited))
    86         else:
    88         else:
    87             rql = 'INSERT %s X' % etype
    89             rql = 'INSERT %s X' % etype
    88         if self.restrictions:
    90         if self.restrictions:
    89             rql += ' WHERE %s' % ','.join(self.restrictions)
    91             rql += ' WHERE %s' % ','.join(self.restrictions)
    90         return rql
    92         return rql
    91 
    93 
    92     def update_query(self, eid):
    94     def update_query(self, eid):
       
    95         assert not self.canceled
    93         varmaker = rqlvar_maker()
    96         varmaker = rqlvar_maker()
    94         var = varmaker.next()
    97         var = varmaker.next()
    95         while var in self.kwargs:
    98         while var in self.kwargs:
    96             var = varmaker.next()
    99             var = varmaker.next()
    97         rql = 'SET %s WHERE X eid %%(%s)s' % (','.join(self.edited), var)
   100         rql = 'SET %s WHERE X eid %%(%s)s' % (','.join(self.edited), var)
   266             self.handle_formfield(form, field, rqlquery)
   269             self.handle_formfield(form, field, rqlquery)
   267         # if there are some inlined field which were waiting for this entity's
   270         # if there are some inlined field which were waiting for this entity's
   268         # creation, add relevant data to the rqlquery
   271         # creation, add relevant data to the rqlquery
   269         for form_, field in req.data['pending_inlined'].pop(entity.eid, ()):
   272         for form_, field in req.data['pending_inlined'].pop(entity.eid, ()):
   270             rqlquery.set_inlined(field.name, form_.edited_entity.eid)
   273             rqlquery.set_inlined(field.name, form_.edited_entity.eid)
   271         if self.errors:
   274         if not rqlquery.canceled:
   272             errors = dict((f.role_name(), unicode(ex)) for f, ex in self.errors)
   275             if self.errors:
   273             raise ValidationError(valerror_eid(entity.eid), errors)
   276                 errors = dict((f.role_name(), unicode(ex)) for f, ex in self.errors)
   274         if eid is None: # creation or copy
   277                 raise ValidationError(valerror_eid(entity.eid), errors)
   275             entity.eid = eid = self._insert_entity(etype, formparams['eid'], rqlquery)
   278             if eid is None: # creation or copy
   276         elif rqlquery.edited: # edition of an existant entity
   279                 entity.eid = eid = self._insert_entity(etype, formparams['eid'], rqlquery)
   277             self._update_entity(eid, rqlquery)
   280             elif rqlquery.edited: # edition of an existant entity
       
   281                 self._update_entity(eid, rqlquery)
       
   282         else:
       
   283             self.errors = []
   278         if is_main_entity:
   284         if is_main_entity:
   279             self.notify_edited(entity)
   285             self.notify_edited(entity)
   280         if '__delete' in formparams:
   286         if '__delete' in formparams:
   281             # XXX deprecate?
   287             # XXX deprecate?
   282             todelete = req.list_form_param('__delete', formparams, pop=True)
   288             todelete = req.list_form_param('__delete', formparams, pop=True)
   313 
   319 
   314                 unlinked_eids = origvalues - value
   320                 unlinked_eids = origvalues - value
   315                 if unlinked_eids:
   321                 if unlinked_eids:
   316                     # Special handling of composite relation removal
   322                     # Special handling of composite relation removal
   317                     self.handle_composite_removal(
   323                     self.handle_composite_removal(
   318                         form, field, unlinked_eids)
   324                         form, field, unlinked_eids, rqlquery)
   319 
   325 
   320                 if rschema.inlined and rqlquery is not None and field.role == 'subject':
   326                 if rschema.inlined and rqlquery is not None and field.role == 'subject':
   321                     self.handle_inlined_relation(form, field, value, origvalues, rqlquery)
   327                     self.handle_inlined_relation(form, field, value, origvalues, rqlquery)
   322                 elif form.edited_entity.has_eid():
   328                 elif form.edited_entity.has_eid():
   323                     self.handle_relation(form, field, value, origvalues)
   329                     self.handle_relation(form, field, value, origvalues)
   325                     form._cw.data['pending_others'].add( (form, field) )
   331                     form._cw.data['pending_others'].add( (form, field) )
   326 
   332 
   327         except ProcessFormError as exc:
   333         except ProcessFormError as exc:
   328             self.errors.append((field, exc))
   334             self.errors.append((field, exc))
   329 
   335 
   330     def handle_composite_removal(self, form, field, removed_values):
   336     def handle_composite_removal(self, form, field, removed_values, rqlquery):
   331         """
   337         """
   332         In EditController-handled forms, when the user removes a composite
   338         In EditController-handled forms, when the user removes a composite
   333         relation, it triggers the removal of the related entity in the
   339         relation, it triggers the removal of the related entity in the
   334         composite. This is where this happens.
   340         composite. This is where this happens.
   335 
   341 
   347                     targettype = form.edited_entity.e_schema
   353                     targettype = form.edited_entity.e_schema
   348                     to_be_removed = unlinked_entity
   354                     to_be_removed = unlinked_entity
   349                 else:
   355                 else:
   350                     targettype = unlinked_entity.e_schema
   356                     targettype = unlinked_entity.e_schema
   351                     to_be_removed = form.edited_entity
   357                     to_be_removed = form.edited_entity
       
   358                     self.info('Edition of %s is cancelled (deletion requested)',
       
   359                               to_be_removed)
       
   360                     rqlquery.canceled = True
   352                 self.info('Scheduling removal of %s as composite relation '
   361                 self.info('Scheduling removal of %s as composite relation '
   353                           '%s was removed', to_be_removed, rdef)
   362                           '%s was removed', to_be_removed, rdef)
   354                 form._cw.data['pending_composite_delete'].add(
   363                 form._cw.data['pending_composite_delete'].add(
   355                     (to_be_removed, field.name,
   364                     (to_be_removed, field.name,
   356                      neg_role(rdef.composite), targettype))
   365                      neg_role(rdef.composite), targettype))