hooks/syncsources.py
changeset 6944 0cf10429ad39
parent 6724 24bf6f181d0e
child 6945 28bf94d062a9
--- 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)) )