hooks/metadata.py
changeset 7399 972ed1843bd8
parent 7336 0c8c386d653b
child 7514 32081892850e
equal deleted inserted replaced
7398:26695dd703d8 7399:972ed1843bd8
    21 
    21 
    22 from datetime import datetime
    22 from datetime import datetime
    23 
    23 
    24 from cubicweb.selectors import is_instance
    24 from cubicweb.selectors import is_instance
    25 from cubicweb.server import hook
    25 from cubicweb.server import hook
       
    26 from cubicweb.server.edition import EditedEntity
    26 
    27 
    27 
    28 
    28 class MetaDataHook(hook.Hook):
    29 class MetaDataHook(hook.Hook):
    29     __abstract__ = True
    30     __abstract__ = True
    30     category = 'metadata'
    31     category = 'metadata'
   140                 session, session.entity_from_eid(self.eidfrom))
   141                 session, session.entity_from_eid(self.eidfrom))
   141         elif ftcontainer == 'object':
   142         elif ftcontainer == 'object':
   142             session.repo.system_source.index_entity(
   143             session.repo.system_source.index_entity(
   143                 session, session.entity_from_eid(self.eidto))
   144                 session, session.entity_from_eid(self.eidto))
   144 
   145 
       
   146 
       
   147 
       
   148 # entity source handling #######################################################
       
   149 
       
   150 class ChangeEntityUpdateCaches(hook.Operation):
       
   151     def postcommit_event(self):
       
   152         self.oldsource.reset_caches()
       
   153         repo = self.session.repo
       
   154         entity = self.entity
       
   155         extid = entity.cw_metainformation()['extid']
       
   156         repo._type_source_cache[entity.eid] = (
       
   157             entity.__regid__, self.newsource.uri, None)
       
   158         if self.oldsource.copy_based_source:
       
   159             uri = 'system'
       
   160         else:
       
   161             uri = self.oldsource.uri
       
   162         repo._extid_cache[(extid, uri)] = -entity.eid
       
   163 
       
   164 class ChangeEntitySourceDeleteHook(MetaDataHook):
       
   165     """support for moving an entity from an external source by watching 'Any
       
   166     cw_source CWSource' relation
       
   167     """
       
   168 
       
   169     __regid__ = 'cw.metadata.source-change'
       
   170     __select__ = MetaDataHook.__select__ & hook.match_rtype('cw_source')
       
   171     events = ('before_delete_relation',)
       
   172 
       
   173     def __call__(self):
       
   174         if (self._cw.deleted_in_transaction(self.eidfrom)
       
   175             or self._cw.deleted_in_transaction(self.eidto)):
       
   176             return
       
   177         schange = self._cw.transaction_data.setdefault('cw_source_change', {})
       
   178         schange[self.eidfrom] = self.eidto
       
   179 
       
   180 class ChangeEntitySourceAddHook(MetaDataHook):
       
   181     __regid__ = 'cw.metadata.source-change'
       
   182     __select__ = MetaDataHook.__select__ & hook.match_rtype('cw_source')
       
   183     events = ('before_add_relation',)
       
   184 
       
   185     def __call__(self):
       
   186         schange = self._cw.transaction_data.get('cw_source_change')
       
   187         if schange is not None and self.eidfrom in schange:
       
   188             newsource = self._cw.entity_from_eid(self.eidto)
       
   189             if newsource.name != 'system':
       
   190                 raise Exception('changing source to something else than the '
       
   191                                 'system source is unsupported')
       
   192             syssource = newsource.repo_source
       
   193             oldsource = self._cw.entity_from_eid(schange[self.eidfrom])
       
   194             entity = self._cw.entity_from_eid(self.eidfrom)
       
   195             # copy entity if necessary
       
   196             if not oldsource.repo_source.copy_based_source:
       
   197                 entity.complete(skip_bytes=False)
       
   198                 entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache)
       
   199                 syssource.add_entity(self._cw, entity)
       
   200             # we don't want the moved entity to be reimported later.  To
       
   201             # distinguish this state, the trick is to change the associated
       
   202             # record in the 'entities' system table with eid=-eid while leaving
       
   203             # other fields unchanged, and to add a new record with eid=eid,
       
   204             # source='system'. External source will then have consider case
       
   205             # where `extid2eid` return a negative eid as 'this entity was known
       
   206             # but has been moved, ignore it'.
       
   207             self._cw.system_sql('UPDATE entities SET eid=-eid,source=%(source)s WHERE eid=%(eid)s',
       
   208                                 {'eid': self.eidfrom, 'source': newsource.name})
       
   209             attrs = {'type': entity.__regid__, 'eid': entity.eid, 'extid': None,
       
   210                      'source': 'system', 'mtime': datetime.now()}
       
   211             self._cw.system_sql(syssource.sqlgen.insert('entities', attrs), attrs)
       
   212             # register an operation to update repository/sources caches
       
   213             ChangeEntityUpdateCaches(self._cw, entity=entity,
       
   214                                      oldsource=oldsource.repo_source,
       
   215                                      newsource=syssource)