diff -r 406a41c25e13 -r 0cf10429ad39 hooks/syncsources.py --- a/hooks/syncsources.py Mon Feb 07 15:13:05 2011 +0100 +++ b/hooks/syncsources.py Mon Feb 07 18:19:36 2011 +0100 @@ -37,12 +37,64 @@ raise ValidationError(self.entity.eid, {None: 'cant remove system source'}) SourceRemovedOp(self._cw, uri=self.entity.name) -class SourceRemovedHook(SourceHook): - __regid__ = 'cw.sources.removed' - __select__ = SourceHook.__select__ & hook.match_rtype('cw_support', 'cw_may_cross') - events = ('after_add_relation',) +# source mapping synchronization. Expect cw_for_source/cw_schema are immutable +# relations (i.e. can't change from a source or schema to another). + +class SourceMappingDeleteHook(SourceHook): + """check cw_for_source and cw_schema are immutable relations + + XXX empty delete perms would be enough? + """ + __regid__ = 'cw.sources.delschemaconfig' + __select__ = SourceHook.__select__ & hook.match_rtype('cw_for_source', 'cw_schema') + events = ('before_add_relation',) def __call__(self): - entity = self._cw.entity_from_eid(self.eidto) - if entity.__regid__ == 'CWRType' and entity.name in ('is', 'is_instance_of', 'cw_source'): - msg = self._cw._('the %s relation type can\'t be used here') % entity.name - raise ValidationError(self.eidto, {role_name(self.rtype, 'subject'): msg}) + if not self._cw.added_in_transaction(self.eidfrom): + msg = self._cw._("can't change this relation") + raise ValidationError(self.eidfrom, {self.rtype: msg}) + + +class SourceMappingChangedOp(hook.DataOperationMixIn, hook.Operation): + def check_or_update(self, checkonly): + session = self.session + # take care, can't call get_data() twice + try: + data = self.__data + except AttributeError: + data = self.__data = self.get_data() + for schemacfg, source in data: + if source is None: + source = schemacfg.source + if session.added_in_transaction(schemacfg.eid): + if not session.deleted_in_transaction(schemacfg.eid): + source.add_schema_config(schemacfg, checkonly=checkonly) + elif session.deleted_in_transaction(schemacfg.eid): + source.delete_schema_config(schemacfg, checkonly=checkonly) + else: + source.update_schema_config(schemacfg, checkonly=checkonly) + + def precommit_event(self): + self.check_or_update(True) + + def postcommit_event(self): + self.check_or_update(False) + + +class SourceMappingChangedHook(SourceHook): + __regid__ = 'cw.sources.schemaconfig' + __select__ = SourceHook.__select__ & is_instance('CWSourceSchemaConfig') + events = ('after_add_entity', 'after_update_entity') + def __call__(self): + if self.event == 'after_add_entity' or ( + self.event == 'after_update_entity' and 'options' in self.entity.cw_edited): + SourceMappingChangedOp.get_instance(self._cw).add_data( + (self.entity, None) ) + +class SourceMappingDeleteHook(SourceHook): + __regid__ = 'cw.sources.delschemaconfig' + __select__ = SourceHook.__select__ & hook.match_rtype('cw_for_source') + events = ('before_delete_relation',) + def __call__(self): + SourceMappingChangedOp.get_instance(self._cw).add_data( + (self._cw.entity_from_eid(self.eidfrom), + self._cw.entity_from_eid(self.eidto)) )