hooks/syncsources.py
branchstable
changeset 7735 71adfd6bab38
parent 7650 278fe9c1f3ad
child 7879 9aae456abab5
--- a/hooks/syncsources.py	Thu Aug 04 12:50:48 2011 +0200
+++ b/hooks/syncsources.py	Thu Aug 04 12:50:49 2011 +0200
@@ -19,6 +19,7 @@
 
 from socket import gethostname
 
+from logilab.common.decorators import clear_cache
 from yams.schema import role_name
 
 from cubicweb import ValidationError
@@ -66,7 +67,7 @@
         SourceRemovedOp(self._cw, uri=self.entity.name)
 
 
-class SourceUpdatedOp(hook.DataOperationMixIn, hook.Operation):
+class SourceConfigUpdatedOp(hook.DataOperationMixIn, hook.Operation):
 
     def precommit_event(self):
         self.__processed = []
@@ -79,13 +80,45 @@
         for source, conf in self.__processed:
             source.repo_source.update_config(source, conf)
 
+
+class SourceRenamedOp(hook.LateOperation):
+
+    def precommit_event(self):
+        source = self.session.repo.sources_by_uri[self.oldname]
+        if source.copy_based_source:
+            sql = 'UPDATE entities SET asource=%(newname)s WHERE asource=%(oldname)s'
+        else:
+            sql = 'UPDATE entities SET source=%(newname)s, asource=%(newname)s WHERE source=%(oldname)s'
+        self.session.system_sql(sql, {'oldname': self.oldname,
+                                      'newname': self.newname})
+
+    def postcommit_event(self):
+        repo = self.session.repo
+        # XXX race condition
+        source = repo.sources_by_uri.pop(self.oldname)
+        source.uri = self.newname
+        source.public_config['uri'] = self.newname
+        repo.sources_by_uri[self.newname] = source
+        repo._type_source_cache.clear()
+        clear_cache(repo, 'source_defs')
+        if not source.copy_based_source:
+            repo._extid_cache.clear()
+            repo._clear_planning_caches()
+            for cnxset in repo.cnxsets:
+                cnxset.source_cnxs[self.oldname] = cnxset.source_cnxs.pop(self.oldname)
+
+
 class SourceUpdatedHook(SourceHook):
     __regid__ = 'cw.sources.configupdate'
     __select__ = SourceHook.__select__ & is_instance('CWSource')
-    events = ('after_update_entity',)
+    events = ('before_update_entity',)
     def __call__(self):
         if 'config' in self.entity.cw_edited:
-            SourceUpdatedOp.get_instance(self._cw).add_data(self.entity)
+            SourceConfigUpdatedOp.get_instance(self._cw).add_data(self.entity)
+        if 'name' in self.entity.cw_edited:
+            oldname, newname = self.entity.cw_edited.oldnewvalue('name')
+            SourceRenamedOp(self._cw, oldname=oldname, newname=newname)
+
 
 class SourceHostConfigUpdatedHook(SourceHook):
     __regid__ = 'cw.sources.hostconfigupdate'
@@ -97,7 +130,7 @@
                    not 'config' in self.entity.cw_edited:
                 return
             try:
-                SourceUpdatedOp.get_instance(self._cw).add_data(self.entity.cwsource)
+                SourceConfigUpdatedOp.get_instance(self._cw).add_data(self.entity.cwsource)
             except IndexError:
                 # XXX no source linked to the host config yet
                 pass