[source] update system table and internal structures on source renaming. Closes #1896721
--- 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
--- a/server/test/unittest_datafeed.py Thu Aug 04 12:50:48 2011 +0200
+++ b/server/test/unittest_datafeed.py Thu Aug 04 12:50:49 2011 +0200
@@ -94,9 +94,26 @@
self.assertTrue(dfsource.latest_retrieval)
self.assertTrue(dfsource.fresh())
+ # test_rename_source
+ req = self.request()
+ req.execute('SET S name "myrenamedfeed" WHERE S is CWSource, S name "myfeed"')
+ self.commit()
+ entity = self.execute('Card X').get_entity(0, 0)
+ self.assertEqual(entity.cwuri, 'http://www.cubicweb.org/')
+ self.assertEqual(entity.cw_source[0].name, 'myrenamedfeed')
+ self.assertEqual(entity.cw_metainformation(),
+ {'type': 'Card',
+ 'source': {'uri': 'myrenamedfeed', 'type': 'datafeed', 'use-cwuri-as-url': True},
+ 'extid': 'http://www.cubicweb.org/'}
+ )
+ self.assertEqual(self.repo._type_source_cache[entity.eid],
+ ('Card', 'system', 'http://www.cubicweb.org/', 'myrenamedfeed'))
+ self.assertEqual(self.repo._extid_cache[('http://www.cubicweb.org/', 'system')],
+ entity.eid)
+
# test_delete_source
req = self.request()
- req.execute('DELETE CWSource S WHERE S name "myfeed"')
+ req.execute('DELETE CWSource S WHERE S name "myrenamedfeed"')
self.commit()
self.failIf(self.execute('Card X WHERE X title "cubicweb.org"'))
self.failIf(self.execute('Any X WHERE X has_text "cubicweb.org"'))