# HG changeset patch # User Sylvain Thénault # Date 1312455049 -7200 # Node ID 71adfd6bab38d44ad68b2dc5458ee2fd8ac45d0a # Parent 59fea81647e5b1a2c247b6d4613ecd666db704e9 [source] update system table and internal structures on source renaming. Closes #1896721 diff -r 59fea81647e5 -r 71adfd6bab38 hooks/syncsources.py --- 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 diff -r 59fea81647e5 -r 71adfd6bab38 server/test/unittest_datafeed.py --- 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"'))