hooks/syncschema.py
changeset 6225 a176e68b7d0d
parent 6173 eb386e473044
parent 6208 07b176640a8c
child 6279 42079f752a9c
--- a/hooks/syncschema.py	Tue Sep 07 17:34:42 2010 +0200
+++ b/hooks/syncschema.py	Mon Sep 13 15:15:21 2010 +0200
@@ -703,6 +703,45 @@
             syssource.update_rdef_unique(session, rdef)
             self.unique_changed = True
 
+class CWUniqueTogetherConstraintAddOp(MemSchemaOperation):
+    entity = None # make pylint happy
+    def precommit_event(self):
+        session = self.session
+        prefix = SQL_PREFIX
+        table = '%s%s' % (prefix, self.entity.constraint_of[0].name)
+        cols = ['%s%s' % (prefix, r.rtype.name)
+                for r in self.entity.relations]
+        dbhelper= session.pool.source('system').dbhelper
+        sql = dbhelper.sql_create_multicol_unique_index(table, cols)
+        session.system_sql(sql)
+
+    # XXX revertprecommit_event
+
+    def postcommit_event(self):
+        eschema = self.session.vreg.schema.schema_by_eid(self.entity.constraint_of[0].eid)
+        attrs = [r.rtype.name for r in self.entity.relations]
+        eschema._unique_together.append(attrs)
+
+class CWUniqueTogetherConstraintDelOp(MemSchemaOperation):
+    entity = oldcstr = None # for pylint
+    cols = [] # for pylint
+    def precommit_event(self):
+        session = self.session
+        prefix = SQL_PREFIX
+        table = '%s%s' % (prefix, self.entity.type)
+        dbhelper= session.pool.source('system').dbhelper
+        cols = ['%s%s' % (prefix, c) for c in self.cols]
+        sql = dbhelper.sql_drop_multicol_unique_index(table, cols)
+        session.system_sql(sql)
+
+    # XXX revertprecommit_event
+
+    def postcommit_event(self):
+        eschema = self.session.vreg.schema.schema_by_eid(self.entity.eid)
+        cols = set(self.cols)
+        unique_together = [ut for ut in eschema._unique_together
+                           if set(ut) != cols]
+        eschema._unique_together = unique_together
 
 # operations for in-memory schema synchronization  #############################
 
@@ -1049,17 +1088,19 @@
 
 
 class AfterAddConstrainedByHook(SyncSchemaHook):
-    __regid__ = 'syncdelconstrainedby'
+    __regid__ = 'syncaddconstrainedby'
     __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constrained_by')
     events = ('after_add_relation',)
 
     def __call__(self):
         if self._cw.added_in_transaction(self.eidfrom):
+            # used by get_constraints() which is called in CWAttributeAddOp
             self._cw.transaction_data.setdefault(self.eidfrom, []).append(self.eidto)
 
 
-class BeforeDeleteConstrainedByHook(AfterAddConstrainedByHook):
+class BeforeDeleteConstrainedByHook(SyncSchemaHook):
     __regid__ = 'syncdelconstrainedby'
+    __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constrained_by')
     events = ('before_delete_relation',)
 
     def __call__(self):
@@ -1075,6 +1116,32 @@
         else:
             CWConstraintDelOp(self._cw, rdef=rdef, oldcstr=cstr)
 
+# unique_together constraints
+# XXX: use setoperations and before_add_relation here (on constraint_of and relations)
+class AfterAddCWUniqueTogetherConstraintHook(SyncSchemaHook):
+    __regid__ = 'syncadd_cwuniquetogether_constraint'
+    __select__ = SyncSchemaHook.__select__ & is_instance('CWUniqueTogetherConstraint')
+    events = ('after_add_entity', 'after_update_entity')
+
+    def __call__(self):
+        CWUniqueTogetherConstraintAddOp(self._cw, entity=self.entity)
+
+
+class BeforeDeleteConstraintOfHook(SyncSchemaHook):
+    __regid__ = 'syncdelconstraintof'
+    __select__ = SyncSchemaHook.__select__ & hook.match_rtype('constraint_of')
+    events = ('before_delete_relation',)
+
+    def __call__(self):
+        if self._cw.deleted_in_transaction(self.eidto):
+            return
+        schema = self._cw.vreg.schema
+        cstr = self._cw.entity_from_eid(self.eidfrom)
+        entity = schema.schema_by_eid(self.eidto)
+        cols = [r.rtype.name
+                for r in cstr.relations]
+        CWUniqueTogetherConstraintDelOp(self._cw, entity=entity, oldcstr=cstr, cols=cols)
+
 
 # permissions synchronization hooks ############################################