server/sources/native.py
changeset 10550 d4bd28d5fca8
parent 10477 ee21c559f94f
child 10575 036f5964e6fe
child 10580 5fbdbbe51867
equal deleted inserted replaced
10549:5fc21bf2684f 10550:d4bd28d5fca8
   561         results = self.process_result(cursor, cnx, cbs)
   561         results = self.process_result(cursor, cnx, cbs)
   562         assert dbg_results(results)
   562         assert dbg_results(results)
   563         return results
   563         return results
   564 
   564 
   565     @contextmanager
   565     @contextmanager
   566     def _storage_handler(self, entity, event):
   566     def _fixup_cw(self, cnx, entity):
       
   567         _cw = entity._cw
       
   568         entity._cw = cnx
       
   569         try:
       
   570             yield
       
   571         finally:
       
   572             entity._cw = _cw
       
   573 
       
   574     @contextmanager
       
   575     def _storage_handler(self, cnx, entity, event):
   567         # 1/ memorize values as they are before the storage is called.
   576         # 1/ memorize values as they are before the storage is called.
   568         #    For instance, the BFSStorage will replace the `data`
   577         #    For instance, the BFSStorage will replace the `data`
   569         #    binary value with a Binary containing the destination path
   578         #    binary value with a Binary containing the destination path
   570         #    on the filesystem. To make the entity.data usage absolutely
   579         #    on the filesystem. To make the entity.data usage absolutely
   571         #    transparent, we'll have to reset entity.data to its binary
   580         #    transparent, we'll have to reset entity.data to its binary
   576         else:
   585         else:
   577             entities = [entity]
   586             entities = [entity]
   578         etype = entities[0].__regid__
   587         etype = entities[0].__regid__
   579         for attr, storage in self._storages.get(etype, {}).items():
   588         for attr, storage in self._storages.get(etype, {}).items():
   580             for entity in entities:
   589             for entity in entities:
   581                 if event == 'deleted':
   590                 with self._fixup_cw(cnx, entity):
   582                     storage.entity_deleted(entity, attr)
   591                     if event == 'deleted':
   583                 else:
   592                         storage.entity_deleted(entity, attr)
   584                     edited = entity.cw_edited
   593                     else:
   585                     if attr in edited:
   594                         edited = entity.cw_edited
   586                         handler = getattr(storage, 'entity_%s' % event)
   595                         if attr in edited:
   587                         to_restore = handler(entity, attr)
   596                             handler = getattr(storage, 'entity_%s' % event)
   588                         restore_values.append((entity, attr, to_restore))
   597                             to_restore = handler(entity, attr)
       
   598                             restore_values.append((entity, attr, to_restore))
   589         try:
   599         try:
   590             yield # 2/ execute the source's instructions
   600             yield # 2/ execute the source's instructions
   591         finally:
   601         finally:
   592             # 3/ restore original values
   602             # 3/ restore original values
   593             for entity, attr, value in restore_values:
   603             for entity, attr, value in restore_values:
   594                 entity.cw_edited.edited_attribute(attr, value)
   604                 entity.cw_edited.edited_attribute(attr, value)
   595 
   605 
   596     def add_entity(self, cnx, entity):
   606     def add_entity(self, cnx, entity):
   597         """add a new entity to the source"""
   607         """add a new entity to the source"""
   598         with self._storage_handler(entity, 'added'):
   608         with self._storage_handler(cnx, entity, 'added'):
   599             attrs = self.preprocess_entity(entity)
   609             attrs = self.preprocess_entity(entity)
   600             sql = self.sqlgen.insert(SQL_PREFIX + entity.cw_etype, attrs)
   610             sql = self.sqlgen.insert(SQL_PREFIX + entity.cw_etype, attrs)
   601             self.doexec(cnx, sql, attrs)
   611             self.doexec(cnx, sql, attrs)
   602             if cnx.ertype_supports_undo(entity.cw_etype):
   612             if cnx.ertype_supports_undo(entity.cw_etype):
   603                 self._record_tx_action(cnx, 'tx_entity_actions', u'C',
   613                 self._record_tx_action(cnx, 'tx_entity_actions', u'C',
   604                                        etype=unicode(entity.cw_etype), eid=entity.eid)
   614                                        etype=unicode(entity.cw_etype), eid=entity.eid)
   605 
   615 
   606     def update_entity(self, cnx, entity):
   616     def update_entity(self, cnx, entity):
   607         """replace an entity in the source"""
   617         """replace an entity in the source"""
   608         with self._storage_handler(entity, 'updated'):
   618         with self._storage_handler(cnx, entity, 'updated'):
   609             attrs = self.preprocess_entity(entity)
   619             attrs = self.preprocess_entity(entity)
   610             if cnx.ertype_supports_undo(entity.cw_etype):
   620             if cnx.ertype_supports_undo(entity.cw_etype):
   611                 changes = self._save_attrs(cnx, entity, attrs)
   621                 changes = self._save_attrs(cnx, entity, attrs)
   612                 self._record_tx_action(cnx, 'tx_entity_actions', u'U',
   622                 self._record_tx_action(cnx, 'tx_entity_actions', u'U',
   613                                        etype=unicode(entity.cw_etype), eid=entity.eid,
   623                                        etype=unicode(entity.cw_etype), eid=entity.eid,
   616                                      ['cw_eid'])
   626                                      ['cw_eid'])
   617             self.doexec(cnx, sql, attrs)
   627             self.doexec(cnx, sql, attrs)
   618 
   628 
   619     def delete_entity(self, cnx, entity):
   629     def delete_entity(self, cnx, entity):
   620         """delete an entity from the source"""
   630         """delete an entity from the source"""
   621         with self._storage_handler(entity, 'deleted'):
   631         with self._storage_handler(cnx, entity, 'deleted'):
   622             if cnx.ertype_supports_undo(entity.cw_etype):
   632             if cnx.ertype_supports_undo(entity.cw_etype):
   623                 attrs = [SQL_PREFIX + r.type
   633                 attrs = [SQL_PREFIX + r.type
   624                          for r in entity.e_schema.subject_relations()
   634                          for r in entity.e_schema.subject_relations()
   625                          if (r.final or r.inlined) and not r in VIRTUAL_RTYPES]
   635                          if (r.final or r.inlined) and not r in VIRTUAL_RTYPES]
   626                 changes = self._save_attrs(cnx, entity, attrs)
   636                 changes = self._save_attrs(cnx, entity, attrs)